Spring boot does not create tables from entities - sql

When I try to save an entity for the first time, I got those errors. It is spring boot.
lifePolicyReconciliationReceivedRepository.save(lifePolicyReconciliationReceived);
this is repository.
I got those errors:
ARJUNA016129: Could not end XA resource com.ibm.db2.jcc.t4.a4#3275401a
com.ibm.db2.jcc.am.XaException: [jcc][t4][10401][12066][4.24.92] XA exception: XA_RBROLLBACK ERRORCODE=-4228, SQLSTATE=null
All fields are filled before this. Entity is this:
#Entity #Table(
schema = "CREAM" // i want to put in that schema // , // name = "D_RECONCILIATION_RECEIVED" // i sometimes give name, but with or without it, errors are taken
)
#Getter
#Setter
#NoArgsConstructor
public class LifePolicyReconciliationReceived extends Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)//i also did GenerationType.IDENTITY but still error
private Long id;
private Long applicationId;
#Temporal(TemporalType.DATE)
private Date receiveDate;
#Temporal(TemporalType.DATE)
private Date startDate;
#Temporal(TemporalType.DATE)
private Date endDate;
}
When i change to Id to .IDENTITY, it becomes:
Caused by: com.ibm.db2.jcc.am.SqlSyntaxErrorException: DB2 SQL Error: SQLCODE=-204, SQLSTATE=42704, SQLERRMC=CREAM.D_RECONCILIATION_RECEIVED, DRIVER=4.24.92
WHen i create manually by going to sql, there is no problem. It can save there but why do i have to do? Spring boot can do it and connect manytoone and other relationships.
Because according to here
DB2 SQL Error: SQLCODE=-204, SQLSTATE=42704
second error is for missing schema. Why doesnt it create itself?
This repository:
public interface LifePolicyReconciliationReceivedRepository extends JpaRepository<LifePolicyReconciliationReceived, Long> {
}
Normally, there was no properties file. Only yml for port. But i created and added this:
spring.jpa.hibernate.ddl-auto=update
And application java file, I added this:
#EntityScan(basePackages = {"com/xxx/xxx/dbmodel, "com.xxxx.xxx.dataaccess""})
#EnableConfigurationProperties
There are maven modules. I am using one of modules. So, I have to give entity path and other one is repository path.
But did not work.
Also, changed to this but still did not work:
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:db2://192.168.xx.xx:60000/FF
spring.datasource.username=qqq
spring.datasource.password=fff
So, when application is starting, there is not the table created. I am checking logs. So after app starts, i try to save. When repository tries to save, it gets errors.
Method threw 'org.springframework.dao.InvalidDataAccessResourceUsageException' exception.

Related

EnityManager does not generate delete query

I'm trying to delete an entity but the delete query is not generated and there's no error shown in the console :
#Override
#Transactional
public void removeClassObject(MyClassObject classObject) {
MyClassObject ip = entityManager.find(MyClassObject.class, classObject.getId());
entityManager.remove(ip);
}
Take notice : #Transactional is from springFramework package
EDIT :
All my configuration are ok, because I already have the merge and persist functions doing there job without any problem it's just the remove method which doesn't generate any sql query and does not remove the given entity.
EDIT 2 :
This is how I obtain my entityManager :
#PersistenceContext(type = PersistenceContextType.TRANSACTION)
protected EntityManager entityManager;
If you are using #Transactional annotation, you should consider using interface for your service, and not only implementation.
#Transactional will need a dynamic proxy to be created on your bean to apply the transactional logic, which can be created if your Service has an interface. Otherwise you would need to manage transaction on your own.
In answer I assume that you create entity manager with
#PersistanceContext annotation and your service has no interface.
For mor information : Spring transactions
EDIT:
Also make sure, that you have enabled transactions in your configuration. Look here for similar error but with wrong configuration LINK

Create Entity by using EntityListener

I have a customer which has an association to a customerBudget entity. A CustomerEntityListener will create a customerBudget entity.
I get the following error:
IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST: de.company.entity.Customer-c4775b5b-413b-0567-3612-e0860bca9300 [new,managed].
the code in onAfterInsert(Customer entity)
LoadContext<Customer> loadContext = LoadContext.create(Customer.class);
loadContext.setId(entity.getId());
Customer customer = dataManager.load(loadContext);
CustomerBudget customerBudget = new CustomerBudget();
customerBudget.setCustomer(customer);
CommitContext commitContext = new CommitContext(customerBudget);
dataManager.commit(commitContext);
How can I create and persist Entites in an EntityListener?
You can implement BeforeInsertEntityListener interface and create a new entity in the current persistence context via EntityManager.
The listener may look as follows:
#Component("demo_CustomerEntityListener")
public class CustomerEntityListener implements BeforeInsertEntityListener<Customer> {
#Inject
private Metadata metadata;
#Inject
private Persistence persistence;
#Override
public void onBeforeInsert(Customer entity) {
CustomerBudget customerBudget = metadata.create(CustomerBudget.class);
customerBudget.setCustomer(entity);
persistence.getEntityManager().persist(customerBudget);
}
}
The new entity will be saved to the database on the transaction commit together with the Customer.
The Metadata.create() method is the preferred way to instantiate entities - for entities with integer identifiers it assigns an ID from a sequence; it also handles entity extension if needed.
Entity listeners work in the transaction that saves the entity, which allows you to make atomic changes in your data - everything will be either saved or discarded together with the entity the listener is invoked on.
Unlike EntityManager, DataManager always creates a new transaction. So you should use it in an entity listener only if you really want to load or save entities in a separate transaction. I'm not sure why you get this particular exception, but your code looks weird: you load an instance of Customer which is in the database instead of using the instance which is passed to the listener. When I tried to run your code on HSQLDB, the server went to infinite lock - the new transaction inside DataManager waits until the current transaction saving the Customer is committed.

UnitOfWork exception triggered by flush between deletes

I am using EclipseLink with container managed entity managers. I have been attempting to determine the cause of a QueryException I sometimes see during delete. The exception description is:
The object MySubEntity is not from this UnitOfWork object space, but the parent session's.
Here's a simplified depiction of the model:
#Entity
public class MyEntity
{
#OneToMany(targetEntity = MySubEntity.class,
cascade = { CascadeType.ALL },
orphanRemoval = true)
#JoinColumn(name = "PARENT_ID")
private List<MySubEntity> subEntities;
}
What I have discovered is that the following succeeds:
MyEntity firstEntity = entityManager.find(MyEntity.class, firstKey);
MyEntity secondEntity = entityManager.find(MyEntity.class, secondKey);
entityManager.remove(firstEntity);
//entityManager.flush();
entityManager.remove(secondEntity);
but if I uncomment the flush, this fails with the QueryException.
The code shown was only written to verify the problem, in practice the deletes don't occur so close together and the flush is implicitly triggered by a read query.
I verified this behavior with both EclipseLink 2.5.1 and 2.6.2. Is this a known EclipseLink bug? I couldn't find one documented. Is this expected behavior?
I have tried calling UnitOfWork.validateObjectSpace() both before and after the first delete but validateObjectSpace() succeeds in both cases.
I encountered this issue in my own work and while looking for help I stumbled upon this question. I can't say for certain if my issue is the same but it is quite similar. My goal is to possibly help others who find this as well.
Let me first explain the slight differences in my model compared to the question. I do not think these differences should be much of a problem however I am including them in the event I am wrong (or it helps someone in the future). The relationship between MyEntity and MySubEntity is not a list and is one to one. It is named accordingly.
#Entity
public class MyEntity
{
#OneToOne(cascade = { CascadeType.REMOVE, CascadeType.PERSIST }, orphanRemoval = true,fetch = FetchType.EAGER)
#JoinColumn(name = "SUB_ENTITY_KEY")
private MySubEntity subEntity;
}
Execution:
My execution is essentially the same as the question. Use the entity manager to remove multiple entities and flush. The flush is not required for my issue to occur (since the entity manager will eventually flush automatically) however it does make it fail faster.
Expected Results:
I expect the removal of both firstEntity and secondEntity and their respective subEntity objects should be removed as well since they are now orphans.
Actual Results:
The UnitOfWork exception described in the question. What I found is that EclipseLink is unable to properly handle the relationship upon remove when multiple MyEntity objects are being removed. This doesn't seem to happen in every situation but if you are able to produce a situation to confuse EclipseLink it will produce this exception consistently.
Solution:
Manually disassociate MyEntity and subEntity prior to removal. This can be done trivially by doing myEntity1.setSubEntity(null);
Even better would be adding it into the pre removal of MyEntity so it is automatically disassociated.
Example:
#PreRemove
public void onRemove() {
this.subEntity= null;
}
Platform Info:
EclipseLink v2.4.3
Oracle JRE 1.7.0_79
Weblogic 12.1.2

Log specific NHibernate SQL queries

I know how to configure NHibernate and log4net to log the resulting SQL of my queries. Is it possible, however, to log only specific queries (for example activating the logging activity before a LINQ query and deactivating it right after the query)?
You can programmatically add and remove appenders to an instance of log4net. So what you could do is when you hit a query that you want to log, programmatically add a new appender, run the query, and then programmatically remove the appender. I have not tested this but I think this should be possible.
Here is a reference for how to programmatically add appenders.
You may log the SQL by yourself with an interceptor, which you would enable when needed.
public class SqlLogInterceptor : EmptyInterceptor
{
private static readonly ILog _log =
LogManager.GetLogger(typeof(SqlLogInterceptor ));
public bool Enabled { get; set; }
public override SqlString OnPrepareStatement(SqlString sql)
{
// Adjust your log level as you see fit.
if (Enabled)
_log.Info(sql);
return sql;
}
}
When opening the session, provide an instance of the interceptor to OpenSession and keep a reference on it.
Set its Enabled property when you need your logging. Provided you have used the interceptor instance with only one session, it will then log only that session SQL.
Parameter values will not be logged with this solution.

WCF Service Reference Will not compile

I currently have a simple WCF service with the following operation:
[OperationContract]
int InsertApplication(Application application);
The Application Parameter is defined as follows:
[DataContract]
public class Application
{
int test = 0;
[DataMember]
public int Test
{
get { return test; }
set { test = value; }
}
}
This service is being consumed within a Windows service with a namespace SpringstoneColoAgent. I added a service reference with no problems called OfficeInternalService. The code that calls the service method is as follows:
Application application = new Application();//= ConvertToApp(app);
application.Test = 1;
int oracleID = client.InsertApplication(application);
However, visual studio is telling me that 'application' is an invalid parameter. On further research I try to build anyway. I get a bunch of errors pointing to the Reference.cs file. Looking at this file I determine all the errors revolve around code that uses the following:
SpringstoneColoAgent.OfficeInternalService._
Where anything it is trying to reference under the service reference name is incorrect. So for example this code is giving an error:
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IOfficeInternalService/InsertApplication", ReplyAction="http://tempuri.org/IOfficeInternalService/InsertApplicationResponse")]
int InsertApplication(SpringstoneColoAgent.OfficeInternalService.Application application);
If I do not fully qualify the namespace and remove SpringstoneColoAgent.OfficeInternalService. so that the code looks like this:
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IOfficeInternalService/InsertApplication", ReplyAction="http://tempuri.org/IOfficeInternalService/InsertApplicationResponse")]
int InsertApplication(Application application);
This will fix the error. I repeated this everywhere I could find the error and everything compiled fine. The downside is that everytime I make a change to the WCF service and need to update the service reference it loses these changes and I have to go back and change them.
I'm guessing I am missing something here and was curious if anyone had any direction or has run into a similar situation.
Thanks for any advice!
The Application class is a known .NET type: http://msdn.microsoft.com/en-us/library/system.windows.forms.application.aspx. Try to work with a different class name to avoid name clashes.
Also try to avoid the int private member in the datacontract. Because it is not a datamember, it is not exposed in the WSDL and a generated proxy class on the client side does not know this private member. This can also cause problems.