In a spring mvc app using hibernate, I am encountering the following error when i try to persist an entity:
java.sql.SQLException: Field 'thirdIds_huid' doesn't have a default value
The database schema is generated by hbm2ddl. How can I change the hibernate code so that these entities can be persisted successfully?
The two entities are AClass and HClass. The code for AClass is::
import javax.persistence.*;
#Entity(name = "AClass")
#Table(name = "a_class")
public class AClass {
private Long auid;
private HClass firstId;
private List<HClass> secondIds;
private List<HClass> thirdIds;
#Id
#Column(name = "auid")
#GeneratedValue(strategy = GenerationType.AUTO)
public Long getAuid(){return auid;}
public void setAuid(Long hid){auid = hid;}
#ManyToOne
public HClass getFirstId(){return firstId;}
public void setFirstId(HClass tid){firstId = tid;}
#OneToMany
public List<HClass> getSecondIds(){return secondIds;}
public void setSecondIds(List<HClass> tid){secondIds = tid;}
#OneToMany
public List<HClass> getThirdIds(){return thirdIds;}
public void setThirdIds(List<HClass> i){thirdIds = i;}
}
The code for HClass is:
import javax.persistence.*;
#Entity(name = "HClass")
#Table(name = "h_class")
public class HClass {
private Long huid;
private String somefield;
#Id
#Column(name = "huid")
#GeneratedValue(strategy = GenerationType.AUTO)
public Long getHuid(){return huid;}
public void setHuid(Long hid){huid = hid;}
#Column(name = "somefield")
public String getSomefield(){return somefield;}
public void setSomefield(String rt){somefield = rt;}
}
The controller code that triggers the error is:
#RequestMapping(value = "/TriggerTheError", method = RequestMethod.GET)
public String processFindForm( HttpServletRequest request, Map<String, Object> model) {
AClass ac = new AClass();
HClass hc = new HClass();
hc.setSomefield("some value goes here");
List<HClass> hcs = new ArrayList<HClass>();
hcs.add(hc);
ac.setSecondIds(hcs);
HClass hc2 = new HClass();
hc2.setSomefield("another value goes here");
List<HClass> hcs2 = new ArrayList<HClass>();
hcs2.add(hc2);
ac.setThirdIds(hcs2);
persistAClass(ac);
return "ReproduceError";
}
public void persistAClass(AClass ac){
if(ac.getThirdIds()!=null){
if(ac.getThirdIds().size()==0){ac.setThirdIds(null);System.out.println("thirdids re-set to null.");}
if(ac.getThirdIds()!=null){
System.out.println("thirdids!=null: size is: "+ac.getThirdIds().size());
for(int dd = 0;dd<ac.getThirdIds().size();dd++){
this.serviceLayer.saveHClass(ac.getThirdIds().get(dd));
}
}
}
if(ac.getSecondIds()!=null){
if(ac.getSecondIds().size()==0){ac.setSecondIds(null);System.out.println("secondids re-set to null.");}
if(ac.getSecondIds()!=null){
System.out.println("secondsid!=null: size is:"+ac.getSecondIds().size());
for(int kk = 0;kk < ac.getSecondIds().size();kk++){
this.serviceLayer.saveHClass(ac.getSecondIds().get(kk));
}
}
}
if(ac.getFirstId()!=null){
System.out.println("firstid!=null: huid value is: "+ac.getFirstId().getHuid());
this.serviceLayer.saveHClass(ac.getFirstId());
}
System.out.println("-------------------- data follows ------------------------------");
for(int a=0;a<ac.getSecondIds().size();a++){
System.out.println("a, secondids somefield are: "+a+", "+ac.getSecondIds().get(a).getSomefield());
}
if(ac.getFirstId()!=null){
String rt = "";
if(ac.getFirstId().getSomefield()!=null){rt = ac.getFirstId().getSomefield();}
System.out.println("first id some field is: "+rt);
}
if(ac.getThirdIds()!=null){
for(int b = 0;b<ac.getThirdIds().size();b++){
String sf = "";
if(ac.getThirdIds().get(b).getSomefield()!=null){sf = ac.getThirdIds().get(b).getSomefield();}
System.out.println("b, third ids somefield are: "+b+", "+sf);
}
}
System.out.println("-------------------- end of data -------------------------------");
this.serviceLayer.saveAClass(ac);
}
Note that the line of code in the controller above that triggers the error is:
this.serviceLayer.saveAClass(ac);
The repository code finally called by the service layer is:
#Override
public void saveAClass(AClass myac) throws DataAccessException{
if (myac.getAuid() == null) {this.em.persist(myac);}
else {this.em.merge(myac);}
}
The complete stack trace is:
11:51:04.334 [http-nio-8080-exec-3] DEBUG o.s.web.servlet.DispatcherServlet - Handler execution resulted in exception - forwarding to resolved error view: ModelAndView: reference to view with name 'exception'; model is {exception=org.springframework.orm.hibernate3.HibernateJdbcException: JDBC exception on Hibernate data access: SQLException for SQL [n/a]; SQL state [HY000]; error code [1364]; could not execute statement; nested exception is org.hibernate.exception.GenericJDBCException: could not execute statement}
org.springframework.orm.hibernate3.HibernateJdbcException: JDBC exception on Hibernate data access: SQLException for SQL [n/a]; SQL state [HY000]; error code [1364]; could not execute statement; nested exception is org.hibernate.exception.GenericJDBCException: could not execute statement
at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:651) ~[spring-orm-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:106) ~[spring-orm-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:517) ~[spring-orm-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:755) ~[spring-tx-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:724) ~[spring-tx-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:475) ~[spring-tx-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:270) ~[spring-tx-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94) ~[spring-tx-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) ~[spring-aop-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204) ~[spring-aop-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at com.sun.proxy.$Proxy27.saveAClass(Unknown Source) ~[na:na]
at example.controller.SomeModelClassController.persistAClass(SomeModelClassController.java:96) ~[SomeModelClassController.class:na]
at example.controller.SomeModelClassController.processFindForm(SomeModelClassController.java:50) ~[SomeModelClassController.class:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_79]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_79]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_79]
at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_79]
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219) ~[spring-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132) ~[spring-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104) ~[spring-webmvc-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745) ~[spring-webmvc-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686) ~[spring-webmvc-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80) ~[spring-webmvc-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925) [spring-webmvc-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856) [spring-webmvc-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936) [spring-webmvc-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827) [spring-webmvc-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:618) [servlet-api.jar:na]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812) [spring-webmvc-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:725) [servlet-api.jar:na]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291) [catalina.jar:8.0.15]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) [catalina.jar:8.0.15]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) [spring-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) [catalina.jar:8.0.15]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) [catalina.jar:8.0.15]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat-websocket.jar:8.0.15]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) [catalina.jar:8.0.15]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) [catalina.jar:8.0.15]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88) [spring-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) [catalina.jar:8.0.15]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) [catalina.jar:8.0.15]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219) [catalina.jar:8.0.15]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) [catalina.jar:8.0.15]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501) [catalina.jar:8.0.15]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142) [catalina.jar:8.0.15]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [catalina.jar:8.0.15]
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610) [catalina.jar:8.0.15]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) [catalina.jar:8.0.15]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:537) [catalina.jar:8.0.15]
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1085) [tomcat-coyote.jar:8.0.15]
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:658) [tomcat-coyote.jar:8.0.15]
at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:222) [tomcat-coyote.jar:8.0.15]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1556) [tomcat-coyote.jar:8.0.15]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1513) [tomcat-coyote.jar:8.0.15]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_79]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_79]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-util.jar:8.0.15]
at java.lang.Thread.run(Thread.java:745) [na:1.7.0_79]
Caused by: org.hibernate.exception.GenericJDBCException: could not execute statement
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:54) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:136) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:58) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.persister.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:1256) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.action.internal.CollectionRecreateAction.execute(CollectionRecreateAction.java:58) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:364) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:356) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:281) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:328) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1234) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:404) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:175) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:75) ~[hibernate-entitymanager-4.2.1.Final.jar:4.2.1.Final]
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:513) ~[spring-orm-3.2.5.RELEASE.jar:3.2.5.RELEASE]
... 57 common frames omitted
Caused by: java.sql.SQLException: Field 'thirdIds_huid' doesn't have a default value
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1078) ~[mysql-connector-java-5.1.27.jar:na]
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4237) ~[mysql-connector-java-5.1.27.jar:na]
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4169) ~[mysql-connector-java-5.1.27.jar:na]
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2617) ~[mysql-connector-java-5.1.27.jar:na]
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2778) ~[mysql-connector-java-5.1.27.jar:na]
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2825) ~[mysql-connector-java-5.1.27.jar:na]
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2156) ~[mysql-connector-java-5.1.27.jar:na]
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2459) ~[mysql-connector-java-5.1.27.jar:na]
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2376) ~[mysql-connector-java-5.1.27.jar:na]
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2360) ~[mysql-connector-java-5.1.27.jar:na]
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:133) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
... 71 common frames omitted
11:51:04.336 [http-nio-8080-exec-3] DEBUG o.s.w.s.v.ContentNegotiatingViewResolver - Requested media types are [text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8] based on Accept header types and producible media types [*/*])
11:51:04.336 [http-nio-8080-exec-3] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Invoking afterPropertiesSet() on bean with name 'exception'
11:51:04.337 [http-nio-8080-exec-3] DEBUG o.s.w.s.v.ContentNegotiatingViewResolver - Returning [org.springframework.web.servlet.view.JstlView: name 'exception'; URL [/WEB-INF/jsp/exception.jsp]] based on requested media type 'text/html'
11:51:04.337 [http-nio-8080-exec-3] DEBUG o.s.web.servlet.DispatcherServlet - Rendering view [org.springframework.web.servlet.view.JstlView: name 'exception'; URL [/WEB-INF/jsp/exception.jsp]] in DispatcherServlet with name 'MinimalDbaseExample'
11:51:04.337 [http-nio-8080-exec-3] DEBUG o.s.web.servlet.view.JstlView - Added model object 'exception' of type [org.springframework.orm.hibernate3.HibernateJdbcException] to request in view with name 'exception'
11:51:04.337 [http-nio-8080-exec-3] DEBUG o.s.web.servlet.view.JstlView - Forwarding to resource [/WEB-INF/jsp/exception.jsp] in InternalResourceView 'exception'
11:51:04.380 [http-nio-8080-exec-3] DEBUG o.s.web.servlet.DispatcherServlet - Successfully completed request
ANSWER
The solution came from the part of #VladMihalcea's answer that involved removing the multiple references to HClass in the list of properties of AClass. Specifically, I created types HClassFirst, HClassSecond, and HClassThird, all with the same properties and methods. This way, hibernate did not get confused by multiple properties of AClass linking to the same type. The app's architecture allows for this. I decided against using inheritance because there are already a lot of links in each table, and I don't want to bump into other errors related to an excess number of foreign keys.
Thus, the solution was not in hibernate annotations. Instead, the solution was in adjusting the model that hibernate is being asked to persist.
I think it's much simpler to use cascading in this example:
#Entity(name = "AClass")
#Table(name = "a_class")
public class AClass {
private Long auid;
private HClass firstId;
private List<HClass> secondIds = new ArrayList<>();
private List<HClass> thirdIds = new ArrayList<>();
#Id
#Column(name = "auid")
#GeneratedValue(strategy = GenerationType.AUTO)
public Long getAuid(){return auid;}
public void setAuid(Long hid){auid = hid;}
#ManyToOne
public HClass getFirstId(){return firstId;}
public void setFirstId(HClass tid){firstId = tid;}
#OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
public List<HClass> getSecondIds(){return secondIds;}
public void setSecondIds(List<HClass> tid){secondIds = tid;}
#OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
public List<HClass> getThirdIds(){return thirdIds;}
public void setThirdIds(List<HClass> i){thirdIds = i;}
}
Then the persisting logic becomes just that:
public void persistAClass(AClass ac){
this.serviceLayer.saveAClass(ac);
}
The original issue might be due to this:
at org.hibernate.action.internal.CollectionRecreateAction.execute(CollectionRecreateAction.java:58) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
This is how you should initialize collections in your entities:
private List<HClass> secondIds = new ArrayList<>();
private List<HClass> thirdIds = new ArrayList<>();
So, when you want to modify the collections, you don't reset them, but rather rely on the dirty checking mechanism to add/remove elements:
AClass ac = new AClass();
HClass hc = new HClass();
hc.setSomefield("some value goes here");
ac.getSecondIds().add(hc);
HClass hc2 = new HClass();
hc2.setSomefield("another value goes here");
ac.getThirdIds().add(hc2);
persistAClass(ac);
During a merge, you should remove the children that no longer belong to a parent and add the new ones coming from your web request.
Edit
I tried your example on my local machine and like the problem is the way you do the mappings. Because you link the Aclass with HClass on 3 different relations (one many-to-one and 2 one-to-many), this is what you get:
create table a_class (auid bigint generated by default as identity (start with 1), firstId_huid bigint, primary key (auid))
create table a_class_h_class (a_class_auid bigint not null, thirdIds_huid bigint not null, secondIds_huid bigint not null)
create table h_class (huid bigint generated by default as identity (start with 1), somefield varchar(255), primary key (huid))
alter table a_class_h_class add constraint UK_qtt8gi008ssnfi4t3mo3tq310 unique (thirdIds_huid)
alter table a_class_h_class add constraint UK_35k583bmbiomo0rc6t74ba41g unique (secondIds_huid)
alter table a_class add constraint FK_1hw1d6sy2yhp9hirqgb6rx6yr foreign key (firstId_huid) references h_class
alter table a_class_h_class add constraint FK_qtt8gi008ssnfi4t3mo3tq310 foreign key (thirdIds_huid) references h_class
alter table a_class_h_class add constraint FK_jng9ogc4rmlmojd31weygk6l9 foreign key (a_class_auid) references a_class
alter table a_class_h_class add constraint FK_35k583bmbiomo0rc6t74ba41g foreign key (secondIds_huid) references h_class
So when you try to enter an entity:
Query:{[insert into a_class (auid, firstId_huid) values (default, ?)][-5]}
Query:{[insert into h_class (huid, somefield) values (default, ?)][some value goes here]}
Query:{[insert into h_class (huid, somefield) values (default, ?)][another value goes here]}
Query:{[insert into a_class_h_class (a_class_auid, secondIds_huid) values (?, ?)][1,1]}
WARN [Alice]: o.h.e.j.s.SqlExceptionHelper - SQL Error: -10, SQLState: 23502
ERROR [Alice]: o.h.e.j.s.SqlExceptionHelper - integrity constraint violation: NOT NULL check constraint; SYS_CT_10096 table: A_CLASS_H_CLASS column: THIRDIDS_HUID
The only fix is to change the Mapping. Instead of 3 HClass associations you should have something else, maybe an inheritance model or something. Always try to model your domain entities on a valid schema.
the "persist detached entity error" is because new transaction is opened for each persist action. For new opened transaction, the entity persisted(the HCClass) in last transaction become "detached".
I suggest you group all you persist action in one transaction, you can do it by move persistAClass to service layer and annotate it #Transactional.
Related
I have a database table named USER and a model class named User which is annotated as #Entity using javax.persistence. When I try to query a user I get the following exception:
SEVERE: Servlet.service() for servlet [Jersey Web Application] in context with path [/myapp] threw exception [java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: User is not mapped [FROM User u WHERE u.username = :username]] with root cause
org.hibernate.hql.internal.ast.QuerySyntaxException: User is not mapped
at org.hibernate.hql.internal.ast.util.SessionFactoryHelper.requireClassPersister(SessionFactoryHelper.java:171)
at org.hibernate.hql.internal.ast.tree.FromElementFactory.addFromElement(FromElementFactory.java:91)
at org.hibernate.hql.internal.ast.tree.FromClause.addFromElement(FromClause.java:79)
at org.hibernate.hql.internal.ast.HqlSqlWalker.createFromElement(HqlSqlWalker.java:324)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElement(HqlSqlBaseWalker.java:3696)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElementList(HqlSqlBaseWalker.java:3585)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromClause(HqlSqlBaseWalker.java:720)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:576)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:313)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:261)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:266)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:189)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:141)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:115)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:77)
at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:153)
at org.hibernate.internal.AbstractSharedSessionContract.getQueryPlan(AbstractSharedSessionContract.java:546)
at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:655)
at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:679)
at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:102)
at com.xxxxxxx.myapp.myapp.sevice.UserService.getUser(UserService.java:32)
at com.xxxxxxx.myapp.myapp.resources.UserResource.getUser(UserResource.java:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:144)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161)
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:205)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)
at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:326)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154)
at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:473)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:427)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:388)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:341)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:228)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
Aug 20, 2017 5:29:58 PM org.apache.catalina.core.StandardContext reload
INFO: Reloading Context with name [/myapp] has started
Aug 20, 2017 5:29:58 PM org.apache.catalina.loader.WebappClassLoaderBase clearReferencesJdbc
WARNING: The web application [myapp] registered the JDBC driver [org.postgresql.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
Aug 20, 2017 5:29:58 PM org.apache.catalina.loader.WebappClassLoaderBase clearReferencesThreads
WARNING: The web application [myapp] appears to have started a thread named [pool-2-thread-1] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093)
java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
java.lang.Thread.run(Thread.java:748)
My query is in a service class called UserService.java which is as below:
import javax.persistence.TypedQuery;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import com.xxxxxx.model.User;
public class UserService {
private static SessionFactory factory;
public UserService() {
}
public User getUser(String username) {
try{
factory = new Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {
System.err.println("Failed to create sessionFactory object." + ex);
throw new ExceptionInInitializerError(ex);
}
Session session = factory.openSession();
Transaction tx = null;
User user = null;
try {
tx = session.beginTransaction();
TypedQuery<User> query = session.createQuery("FROM User u WHERE u.username = :username", User.class).setParameter("username", username);
user = query.getSingleResult();
} catch(HibernateException e) {
if (tx != null) {
tx.rollback();
}
e.printStackTrace();
} finally {
session.close();
}
return user;
}
}
My model class is below:
import javax.persistence.*;
#Entity
#Table(name="USER")
public class User {
#Id #GeneratedValue
#Column(name="id")
private long id;
#Column(name="username", unique=true)
private String username;
#Column(name="email")
private String email;
#Column(name="created")
private Timestamp created;
public User(long id, String username, String email) {
this.id = id;
this.username = username;
this.email = email;
}
}
For most people who had the same issue it seems that they were using the table name instead of the entity name. However, in my case, I think I'm using the correct entity name. I also tried removing the arguments and body of the constructor of the User but didn't help.
For clarity, below is my hibernate.cfg.xml:
<hibernate-configuration>
<session-factory>
<!-- connection settings -->
<property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
<property name="hibernate.connection.url">jdbc:postgresql://localhost:5432/myapp</property>
<property name="hibernate.connection.username">admin</property>
<property name="hibernate.connection.password">xxxxx</property>
<!-- sql dialect -->
<property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>
<!-- mapping files -->
<!-- dev config - remove at prod -->
<property name="hibernate.hbm2ddl.auto">update</property>
</session-factory>
</hibernate-configuration>
For some reason, the annotation is not being processed. You either need to create a mapping file and include in your config, https://www.tutorialspoint.com/hibernate/hibernate_mapping_files.htm or as long as I remember there is a way to specify annotation configuration during hibernate session creation where you specify annotated entities. You are probably missing that part. Please, check this for reference Add Annotated Class in Hibernate by adding all classes in some package. JAVA
I have created a repository for my entity and I added two methods to it as following :
#Modifying
#Query("UPDATE Offre o SET o.state = 'DISABLED' where o.codeOffre=:x")
void disable(#Param("x") Long offre);
#Modifying
#Query("UPDATE Offre o SET o.state = 'REMOVED' where o.codeOffre=:x")
void remove(#Param("x") Long offre);
Offre entity :
#Entity
public class Offre implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "CODE_OFFRE")
private Long codeOffre;
private String titre;
#Enumerated(EnumType.STRING)
#Column(columnDefinition = "ENUM('ENABLED', 'DISABLED', 'REMOVED') DEFAULT 'ENABLED'")
private State state;
//Getters,Setters
}
and this is my service class :
#Service
public class OffreMetierImpl implements IOffreMetier {
#Autowired
private OffreRepository offreRepository;
#Override
#Modifying
public boolean removeOffre(Long codeOffre) {
offreRepository.remove(codeOffre);
return true;
}
#Override
#Modifying
public boolean disableOffre(Long codeOffre) {
offreRepository.disable(codeOffre);
return true;
}
// Other methods
}
but when I call offreRepository.remove I'm getting this error message :
failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query] with root cause javax.persistence.TransactionRequiredException: Executing an update/delete query
How can I solve this problem ?
Edit :
full stack trace :
2016-03-23 12:22:51,076 [http-nio-8080-exec-10] ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query] with root cause
javax.persistence.TransactionRequiredException: Executing an update/delete query
at org.hibernate.jpa.spi.AbstractQueryImpl.executeUpdate(AbstractQueryImpl.java:71)
at org.springframework.data.jpa.repository.query.JpaQueryExecution$ModifyingExecution.doExecute(JpaQueryExecution.java:238)
at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:78)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:100)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:91)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:462)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:440)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:131)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
at com.sun.proxy.$Proxy101.remove(Unknown Source)
at com.capValue.Rekrute.metierImpl.OffreMetierImpl.removeOffre(OffreMetierImpl.java:44)
at com.capValue.Rekrute.service.OffreService.removeOffre(OffreService.java:21)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:817)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:731)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:968)
at org.springframework.web.servlet.FrameworkServlet.doDelete(FrameworkServlet.java:892)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:654)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:844)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:87)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:522)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1095)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:672)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Please make sure that following things are correct at your end.
Your #Modifying annotation should be wrapped up with #Transactional attribute which helps post-processor wraps #Transactional annotated bean methods with an AOP method interceptor which handles transactional behavior.
example
#Modifying
#Transactional
#Query("UPDATE Offre o SET o.state = 'DISABLED' where o.codeOffre=:x")
void disable(#Param("x") Long offre);
Also make sure entries for context:component-scan and
<tx:annotation-driven /> declared at application level (in application context.
Please refer post1 post2 for more information regards.
I have Java Spring MVC application. I am trying to do CRUD on one table, say Employee.
When I am trying to create a new Employee, it saves and adds a new entry in database. But when I am trying to update an Employee, I am updating that row, and I am trying to add a new row, with the old values of the same employee and setting one field to false.
Here is my ServiceImpl
public class EmployeeServiceImpl extends
GenericManagerImpl<Employee, Long> implements
EmployeeService {
#Override
public void save(Employee employee) {
Employee newEmpl = employee;
Date date = new Date();
Long empKey = employee.getEmpKey();
if (empKey) != null) {
oldEmp = (Employee) employeeDao.get();
oldEmp.setActive(false);
oldEmp.setEmpKey(null);
employeeDao.save(oldEmp);
} else {
employee.setCreated(date);
}
employee.setUpdated(date);
employee.setActive(true);
employeeDao.save(employee);
}
}
When I am creating a new entry, it is working fine. But when I am trying to update one entry, then it showing the exception
org.springframework.orm.hibernate4.HibernateSystemException: identifier of an instance of com.table.model.Employee was altered from 4 to null; nested exception is org.hibernate.HibernateException: identifier of an instance of com.table.model.Employee was altered from 4 to null
at org.springframework.orm.hibernate4.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:206)
at org.springframework.orm.hibernate4.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:606)
at org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:488)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:392)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at com.sun.proxy.$Proxy77.save(Unknown Source)
at com.table.webapp.controllers.EmployeeController.saveEmployee(EmployeeController.java:164)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:100)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:604)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:565)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:409)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1044)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:313)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.hibernate.HibernateException: identifier of an instance of com.table.model.Employee was altered from 4 to null
at org.hibernate.event.internal.DefaultFlushEntityEventListener.checkId(DefaultFlushEntityEventListener.java:82)
at org.hibernate.event.internal.DefaultFlushEntityEventListener.getValues(DefaultFlushEntityEventListener.java:194)
at org.hibernate.event.internal.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:156)
at org.hibernate.event.internal.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:225)
at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:99)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1213)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:402)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:175)
at org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:480)
... 43 more
I have checked this SO question, but they are using Query. My logic is in the Service Impl and not in DAO.
How can I alter the id and save as a new entry in database?
Thanks.
You shouldn't do that - it's in the JPA spec somewhere that one must not change a primary key.
What you could do is add a clone/copy method to your Employee class and use that to copy everything but the ID and then persist that new object.
Cheers,
So I have a register Form that is able to send a profile picture to be stored in my database using ibatis but when I try to do the insert i get a nullpointerexception
stacktrace
SEVERE: Servlet.service() for servlet [volts] in context with path [/Mugenjou] threw exception [Request processing failed; nested exception is org.springframework.jdbc.UncategorizedSQLException: SqlMapClient operation; uncategorized SQLException for SQL []; SQL state [null]; error code [0];
--- The error occurred in com/mugenjou/integration/sql.xml.
--- The error occurred while applying a parameter map.
--- Check the sql.register-InlineParameterMap.
--- Check the parameter mapping for the 'picture' property.
--- Cause: java.lang.NullPointerException; nested exception is com.ibatis.common.jdbc.exception.NestedSQLException:
--- The error occurred in com/mugenjou/integration/sql.xml.
--- The error occurred while applying a parameter map.
--- Check the sql.register-InlineParameterMap.
--- Check the parameter mapping for the 'picture' property.
--- Cause: java.lang.NullPointerException] with root cause
java.lang.NullPointerException
at com.ibatis.sqlmap.engine.type.UnknownTypeHandler.setParameter(UnknownTypeHandler.java:69)
at com.ibatis.sqlmap.engine.mapping.parameter.ParameterMap.setParameter(ParameterMap.java:166)
at com.ibatis.sqlmap.engine.mapping.parameter.ParameterMap.setParameters(ParameterMap.java:126)
at com.ibatis.sqlmap.engine.execution.SqlExecutor.executeUpdate(SqlExecutor.java:78)
at com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.sqlExecuteUpdate(MappedStatement.java:216)
at com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeUpdate(MappedStatement.java:94)
at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.insert(SqlMapExecutorDelegate.java:393)
at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.insert(SqlMapSessionImpl.java:82)
at org.springframework.orm.ibatis.SqlMapClientTemplate$8.doInSqlMapClient(SqlMapClientTemplate.java:366)
at org.springframework.orm.ibatis.SqlMapClientTemplate.execute(SqlMapClientTemplate.java:200)
at org.springframework.orm.ibatis.SqlMapClientTemplate.insert(SqlMapClientTemplate.java:364)
at com.mugenjou.integration.BusinessServiceImpl.registerUser(BusinessServiceImpl.java:76)
at com.mugenjou.control.controller.register(controller.java:101)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:174)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:421)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:409)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:771)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:1813)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Once I get the file I tried converting it to a form that could be read using these too methods, both yield the same results as shown in the stacktrace. One converts to a SerialBlob the other to a ByteArrayInputStream.
private ByteArrayInputStream convertMultipartFile(MultipartFile file) throws IOException, SQLException {
byte[] bytes = file.getBytes();
return new ByteArrayInputStream(bytes);
//return new SerialBlob(bytes);
}
SQL.XML:
<insert id ="register" parameterClass ="java.util.Map">
INSERT INTO ACCOUNT_INFO (FNAME, LNAME, ACCOUNT_NAME, PASSWORD, STATUS, CREATION_DATE, LAST_ACCESSED, PROFILE_PICTURE)
VALUES (#fname#, #lname#, #account_name#, #pwd#, 0, #creation_date#, #last_accessed#, #picture#)
</insert>
BusinessServiceImpl
#Override
#SuppressWarnings({ "unchecked", "rawtypes" })
public void registerUser(ByteArrayInputStream picture, String fname, String lname, String account_name,
String pwd) {
sqlMap = getSqlMapClientTemplate();
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date = new Date();
Map params = new HashMap();
params.put("fname", fname);
params.put("lname", lname);
params.put("account_name", account_name);
params.put("pwd", pwd);
params.put("creation_date", dateFormat.format(date));
params.put("last_accessed", "0000-00-00 00:00:00");
params.put("picture", picture);
sqlMap.insert("sql.register", params);
}
Solved this by converting the MultipartFile to an InputStream and then storing
I have a #Transactional service performing a persist action into an oracle DB. If i run a persist breaking a unique violation i get the expected rollbackException:ConstraintException.
The problem is that any subsequent request (even if not breaking the unique constraint) to persist throws the same exception.
It seems like JPA is not clearing the object to persist out of its transaction manager? Am i even close? I need a little explaination.
Repo:
#Repository
public class UserRepository {
#PersistenceContext(type=PersistenceContextType.EXTENDED)
private EntityManager em;
public User findUserById(long id){
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<User> query = builder.createQuery(User.class);
Root<User> root = query.from(User.class);
Predicate whereClause = builder.equal(root.get(User_.userId), id);
return em.createQuery(query.where(whereClause)).getSingleResult();
}
public User findUserByCredentials(String credentials){
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<User> query = builder.createQuery(User.class);
Root<User> root = query.from(User.class);
Predicate whereClause = builder.equal(root.get(User_.credentials), credentials);
return em.createQuery(query.where(whereClause)).getSingleResult();
}
public void registerUser(User user){
em.persist(user);
}
}
ServiceImpl:
#Transactional(readOnly=true)
#Service("userService")
public class UserServiceImpl implements UserService {
#Resource
private UserRepository userRepository;
public void setUserRepository(UserRepository userRepository) {
this.userRepository = userRepository;
}
public User findUserById(long id) {
return userRepository.findUserById(id);
}
public User findUserByCredentials(String credentials){
return userRepository.findUserByCredentials(credentials);
}
#Transactional(readOnly=false)
public void registerUser(User user){
userRepository.registerUser(user);
}
}
error throw in endpoint:
#PayloadRoot(localPart="RegisterUserRequest", namespace = "http://www.missingwire.com/schemas/User")
public RegisterUserResponseDocument registerUser(RegisterUserRequestDocument requestDoc){
RegisterUserRequest request = requestDoc.getRegisterUserRequest();
User user = new User();
user.setCredentials(request.getCredentials());
user.setPassword(request.getPassword());
user.setHonorRating(BigDecimal.valueOf(STARTING_USER_HONOR_RATING));
user.setAccountActive(true);
user.setDateCreated(new Date());
user.setVerified(false);
UserProfile userProfile = new UserProfile();
userProfile.setEmailAddress(request.getEmail());
userProfile.setFirstName(request.getFirstName());
userProfile.setLastName(request.getLastName());
userProfile.setDateCreated(new Date());
userProfile.setUser(user);
user.setUserProfile(userProfile);
**userService.registerUser(user);** //HERE IS THE EXCEPTION THROW
RegisterUserResponseDocument responseDoc = RegisterUserResponseDocument.Factory.newInstance();
RegisterUserResponse response = responseDoc.addNewRegisterUserResponse();
UserType userType = response.addNewUser();
userType.setAccountActive(user.getAccountActive());
userType.setCredentials(user.getCredentials());
userType.setDateCreated(DateConverter.convertDateToXML(user.getDateCreated()));
userType.setUserId(user.getUserId());
userType.setVerified(user.getVerified());
return responseDoc;
}
Exception:
org.springframework.orm.jpa.JpaSystemException: Error while committing
the transaction; nested exception is
javax.persistence.RollbackException: Error while committing the
transaction at
org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:311)
at
org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:102)
at
org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerSynchronization.convertException(ExtendedEntityManagerCreator.java:501)
at
org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerSynchronization.afterCommit(ExtendedEntityManagerCreator.java:481)
at
org.springframework.transaction.support.TransactionSynchronizationUtils.invokeAfterCommit(TransactionSynchronizationUtils.java:133)
at
org.springframework.transaction.support.TransactionSynchronizationUtils.triggerAfterCommit(TransactionSynchronizationUtils.java:121)
at
org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerAfterCommit(AbstractPlatformTransactionManager.java:953)
at
org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:796)
at
org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
at
org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393)
at
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy37.registerUser(Unknown Source) at
com.missingwire.achieve.soa.endpoint.UserEndpoint.registerUser(UserEndpoint.java:76)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616) at
org.springframework.ws.server.endpoint.MethodEndpoint.invoke(MethodEndpoint.java:132)
at
org.springframework.ws.server.endpoint.adapter.MarshallingMethodEndpointAdapter.invokeInternal(MarshallingMethodEndpointAdapter.java:140)
at
org.springframework.ws.server.endpoint.adapter.AbstractMethodEndpointAdapter.invoke(AbstractMethodEndpointAdapter.java:53)
at
org.springframework.ws.server.MessageDispatcher.dispatch(MessageDispatcher.java:231)
at
org.springframework.ws.server.MessageDispatcher.receive(MessageDispatcher.java:172)
at
org.springframework.ws.transport.support.WebServiceMessageReceiverObjectSupport.handleConnection(WebServiceMessageReceiverObjectSupport.java:88)
at
org.springframework.ws.transport.http.WebServiceMessageReceiverHandlerAdapter.handle(WebServiceMessageReceiverHandlerAdapter.java:57)
at
org.springframework.ws.transport.http.MessageDispatcherServlet.doService(MessageDispatcherServlet.java:221)
at
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:669)
at
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:585)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637) 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:679) Caused by:
javax.persistence.RollbackException: Error while committing the
transaction at
org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:93) at
org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerSynchronization.afterCommit(ExtendedEntityManagerCreator.java:478)
... 39 more Caused by: javax.persistence.PersistenceException:
org.hibernate.exception.ConstraintViolationException: Could not
execute JDBC batch update at
org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1235)
at
org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1168)
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:81)
... 40 more Caused by:
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.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:114)
at
org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:109)
at
org.hibernate.jdbc.AbstractBatcher.prepareBatchStatement(AbstractBatcher.java:244)
at
org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2395)
at
org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2858)
at
org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:79)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:267) at
org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:259)
at
org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:178)
at
org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at
org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1206) at
org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:375) at
org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:137)
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:76)
... 40 more Caused by: java.sql.BatchUpdateException: ORA-00001:
unique constraint (ACHIEVE.SYS_C0016488) violated
at
oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10070)
at
oracle.jdbc.driver.OracleStatementWrapper.executeBatch(OracleStatementWrapper.java:213)
at
org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
at
org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
You're injecting an entity manager for an extended persistence context. That means that the lifetime of the persistence context is not tied to the lifetime of the transaction: it stays open until you close it explicitely.
Since you got a RollbackException, the persistence context is in a dirty, inconsistent state, and the only thing you can do is close it immediately.
If the persistence context was a transactional one, it would be closed automatically. But since you're using an extended context, it's up to you to close it explicitely.
Make sure to read and understand the following section of the Spring documentation:
The #PersistenceContext annotation has an optional attribute type,
which defaults to PersistenceContextType.TRANSACTION. This default is
what you need to receive a shared EntityManager proxy. The
alternative, PersistenceContextType.EXTENDED, is a completely
different affair: This results in a so-called extended EntityManager,
which is not thread-safe and hence must not be used in a concurrently
accessed component such as a Spring-managed singleton bean. Extended
EntityManagers are only supposed to be used in stateful components
that, for example, reside in a session, with the lifecycle of the
EntityManager not tied to a current transaction but rather being
completely up to the application.
Adding:
#TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
To methods you want to exclude transactionallity (queries, for example), you'll avoid this problem.