Can you please advise what is wrong here. This is how my method in the controller class looks like
public static void save(Long jobId, Long posetByUserId) throws Exception
{
try{
java.util.Date date = new java.util.Date();
SavedJob job = SavedJob.findByUserIdJobId(connectedUserID(), jobId); //place 1
String validationText = null;
if(job != null){ //place 2
validationText = play.i18n.Messages.get("saved.already");
renderJSON(validationText);
}else{
SavedJob saveJob = new SavedJob();
saveJob.userID = connectedUserID();
saveJob.jobId = jobId;
saveJob.insertDate = date;
saveJob.updateDate = date;
saveJob.posetByUserId = posetByUserId;
saveJob.message = play.i18n.Messages.get("save.saved");
UserProfile userProfile = connectedUser();
userProfile.arlSavedJobs.add(saveJob);
UserProfile.saveUser(userProfile);
.....
}
.......
}
I call the above method using AJAX.
Case 1
When I run play in development mode(not tomcat) and specify the thread pool as 1 all works well.
Case 2
I deployed this to tomcat +lighttpd. The above method fails.
If I call the above method twice it seems like the first request is at “place 1” above in the mean time second request reached “place 2” and gives an error that “saved.already”. The request are not serialized.
I am sure I am doing something wrong here but can you please advise. I need both the requests to save the two items.
Thanks for help.
I am still trying to debug further. Apologies if I mislead, it seems like the problem is down to hibernate trying to do a insert instead of update.
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:96)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
hibernate tries to fire an insert for an already saved entiry instead of an update
So for case 2 below : I send 2 requests.
Request 1 gets saved down and now I have one object in userProfile.arlSavedJobs.add(saveJob);
Request 2 comes so should result into 1 insert and 1 update but I can see hibernate tries to fire two inserts and gives unique constraint exception. Any ideas?
Please note UserProfile.saveUser(userProfile); performs a merge on userprofile. After merge it calls an insert instead of update for already saved entity..?
Sure much appreciated.
After investigation this is where I am at: When the first request comes it adds the object to the list at this place: userProfile.arlSavedJobs.add(saveJob); A save works fine. When the second request comes now this list “arlSavedJobs” already have a object and second request adds one more object to the same list.
When it reaches inle “UserProfile.saveUser(userProfile);” and tries to save it, it should fire 1 insert for new object and 1 update for already existing object(added by request 1). However it fires 2 inserts for both the objects and gives a unique constraint exception. The stack tracke is as follows:
[2012-02-23 23:37:39,914]DEBUG 21530[http-8080-3] – org.hibernate.jdbc.util.SQLStatementLogger.logStatement(SQLStatementLogger.java:111) – insert into SAVED_JOB (DELETE_FLAG, INSERT_DATE, POSTED_BY_USER_ID, UPDATE_DATE, JOB_ID, USER_ID) values (?, ?, ?, ?, ?, ?)
[2012-02-23 23:37:39,967]DEBUG 21583[http-8080-3] – org.hibernate.jdbc.util.SQLStatementLogger.logStatement(SQLStatementLogger.java:111) – insert into SAVED_JOB (DELETE_FLAG, INSERT_DATE, POSTED_BY_USER_ID, UPDATE_DATE, JOB_ID, USER_ID) values (?, ?, ?, ?, ?, ?)
[2012-02-23 23:37:40,019]ERROR 21635[http-8080-3] – org.hibernate.util.JDBCExceptionReporter.logExceptions(JDBCExceptionReporter.java:234) – Duplicate entry ‘4-1’ for key ‘PRIMARY’
[2012-02-23 23:37:40,075]ERROR 21691[http-8080-3] – org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:348) – Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:96)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:268)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:184)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:345)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216)
at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:795)
at play.db.jpa.JPABase._save(JPABase.java:47)
at play.db.jpa.GenericModel.save(GenericModel.java:184)
at models.UserProfile.saveUser(UserProfile.java:401)
at controllers.JTLeadsController.saveLead(JTLeadsController.java:202)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at play.mvc.ActionInvoker.invokeWithContinuation(ActionInvoker.java:546)
at play.mvc.ActionInvoker.invoke(ActionInvoker.java:500)
at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:476)
at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:471)
at play.mvc.ActionInvoker.invoke(ActionInvoker.java:159)
at play.server.ServletWrapper$ServletInvocation.execute(ServletWrapper.java:540)
at play.Invoker$Invocation.run(Invoker.java:265)
at play.server.ServletWrapper$ServletInvocation.run(ServletWrapper.java:531)
at play.Invoker.invokeInThread(Invoker.java:67)
at play.server.ServletWrapper.service(ServletWrapper.java:130)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:662)
Caused by: java.sql.BatchUpdateException: Duplicate entry ‘4-1’ for key ‘PRIMARY’
at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:2018)
at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1449)
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeBatch(NewProxyPreparedStatement.java:1723)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
… 37 more
javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1214)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1147)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1153)
at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:798)
at play.db.jpa.JPABase._save(JPABase.java:47)
at play.db.jpa.GenericModel.save(GenericModel.java:184)
at models.UserProfile.saveUser(UserProfile.java:401)
at controllers.JTLeadsController.saveLead(JTLeadsController.java:202)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at play.mvc.ActionInvoker.invokeWithContinuation(ActionInvoker.java:546)
at play.mvc.ActionInvoker.invoke(ActionInvoker.java:500)
You have three places of possible errors: