{"id":3057,"date":"2014-03-15T03:27:06","date_gmt":"2014-03-15T03:27:06","guid":{"rendered":"https:\/\/unknownerror.org\/index.php\/2014\/03\/15\/spring-exception-translation-isnt-working-with-jpa-collection-of-common-programming-errors-2\/"},"modified":"2014-03-15T03:27:06","modified_gmt":"2014-03-15T03:27:06","slug":"spring-exception-translation-isnt-working-with-jpa-collection-of-common-programming-errors-2","status":"publish","type":"post","link":"https:\/\/unknownerror.org\/index.php\/2014\/03\/15\/spring-exception-translation-isnt-working-with-jpa-collection-of-common-programming-errors-2\/","title":{"rendered":"Spring exception translation isn&#39;t working with JPA-Collection of common programming errors"},"content":{"rendered":"<p>My dao class <code>com.myapp.dao.hibernate.XyzDaoImpl<\/code> is annotated with <code>@Repository<\/code><\/p>\n<pre><code>@Repository\npublic class UserDaoImpl extends GenericDaoJpa implements UserDao {\n\n...\n    @Override\n    public void saveUser(User user) throws Exception{\n        entityManager.persist(user);\n    }\n...\n}\n<\/code><\/pre>\n<p>My <code>app-data.xml<\/code> is as follow:<\/p>\n<pre><code>\n       \n        \n       \n     \n     \n        \n  \n\n\n    \n    \n\n    \n    \n\n    \n        \n    \n\n    \n    \n\n\n     \n    \n\n\n \n\n    \n    \n\n   \n\n \n<\/code><\/pre>\n<p>Now, in my jUnit test method, I deliberately insert a duplicate object and I got <code>javax.persistence.PersistenceException<\/code> instead of a spring exception.<\/p>\n<pre><code>@Test public void testSaveUser() {\n        String login = \"duplicateLogin\";\n\n        User user = new User();\n        user.setLogin(login);\n        user.setPasswd(\"pass\");\n        InformationBean rep = ms.saveUser(user);\n        assertEquals(Constants.REPLY_403, rep);\n        System.out.println(\"user was not saved \"+user);     \n}\n\n\n@Service\npublic class MessagingService{\n...\n\n@Transactional(propagation=Propagation.REQUIRED)\npublic InformationBean saveUser(User user) {\n    InformationBean info ;\n    try {\n        userDao.saveUser(user);\n        info = Constants.REPLY_200;\n    }catch(DataIntegrityViolationException ex) {\n        logger.warn(\"login already used.\");\n        info = Constants.REPLY_403;\n    }catch(ConstraintViolationException cve) {\n        logger.warn(\"login already used.\");\n        info = Constants.REPLY_403;\n    }\n    catch(Exception e) {\n        logger.error(\"Oups error\",e);       \n        info = Constants.REPLY_500;\n    }\n\n    return info;\n}\n...\n}\n<\/code><\/pre>\n<p>Here is the complete stack trace<\/p>\n<pre><code>DEBUG - Creating new transaction with name [com.myapp.service.MessagingService.saveUser]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''\nDEBUG - Opened new EntityManager [org.hibernate.ejb.EntityManagerImpl@f6852d] for JPA transaction\nDEBUG - Exposing JPA transaction as JDBC transaction [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@79df82]\nHibernate: insert into User (email, login, passwd) values (?, ?, ?)\n8928 [main] WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: 1062, SQLState: 23000\n8929 [main] ERROR org.hibernate.util.JDBCExceptionReporter - Duplicate entry 'u123456789012' for key 2\nERROR - Oups error\njavax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not insert: [com.myapp.model.User]\n    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1235)\n    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1168)\n    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1174)\n    at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:674)\n    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)\n    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)\n    at java.lang.reflect.Method.invoke(Method.java:597)\n    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:240)\n    at $Proxy32.persist(Unknown Source)\n    at com.myapp.dao.hibernate.UserDaoImpl.saveUser(UserDaoImpl.java:60)\n    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)\n    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)\n    at java.lang.reflect.Method.invoke(Method.java:597)\n    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)\n    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)\n    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)\n    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:155)\n    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)\n    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)\n    at $Proxy34.saveUser(Unknown Source)\n    at com.myapp.service.MessagingService.saveUser(MessagingService.java:237)\n    at com.myapp.service.MessagingService$$FastClassByCGLIB$$48584635.invoke()\n    at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)\n    at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:688)\n    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)\n    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)\n    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)\n    at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:621)\n    at com.myapp.service.MessagingService$$EnhancerByCGLIB$$4c0c06a9.saveUser()\n    at com.myapp.service.MessagingServiceTest.testSaveUser(MessagingServiceTest.java:112)\n    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)\n    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)\n    at java.lang.reflect.Method.invoke(Method.java:597)\n    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)\n    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)\n    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)\n    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)\n    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)\n    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)\n    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)\n    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)\n    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)\n    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)\n    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)\n    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)\n    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)\n    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)\n    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)\n    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)\n    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)\n    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)\n    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)\n    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)\n    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)\n    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)\n    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)\n    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)\nCaused by: org.hibernate.exception.ConstraintViolationException: could not insert: [com.myapp.model.User]\n    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:96)\n    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)\n    at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:64)\n    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2329)\n    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2836)\n    at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:71)\n    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:268)\n    at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:321)\n    at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)\n    at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:130)\n    at org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:69)\n    at org.hibernate.event.def.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:179)\n    at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:135)\n    at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:61)\n    at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:800)\n    at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:774)\n    at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:778)\n    at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:668)\n    ... 56 more\nCaused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'u123456789012' for key 2\n    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)\n    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)\n    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)\n    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)\n    at com.mysql.jdbc.Util.handleNewInstance(Util.java:409)\n    at com.mysql.jdbc.Util.getInstance(Util.java:384)\n    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1041)\n    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3562)\n    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3494)\n    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1960)\n    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2114)\n    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2696)\n    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2105)\n    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2398)\n    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2316)\n    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2301)\n    at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:101)\n    at org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAndExtract(IdentityGenerator.java:94)\n    at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:57)\n    ... 71 more\nDEBUG - Initiating transaction commit\nDEBUG - Committing JPA transaction on EntityManager [org.hibernate.ejb.EntityManagerImpl@f6852d]\nDEBUG - Closing JPA EntityManager [org.hibernate.ejb.EntityManagerImpl@f6852d] after transaction\nDEBUG - Closing JPA EntityManager\n<\/code><\/pre>\n<p><em>EDIT1: After removing the throws Exception from the saveUser() DAO method, it seems that Spring exception translation is working. My service method catchs DataIntegrityViolationException and return normally. However, the test method doesn&#8217;t get the return but instead get an exception: TransactionSystemException. How can I avoid such unwanted exception that breaks everything?<\/em><\/p>\n<p><em>Edit2: Spring exception translation was working fine, the problem comes from JPA\/EntityManager. See the complete story and how I managed to solve it: http:\/\/tinyurl.com\/439dmul<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>My dao class com.myapp.dao.hibernate.XyzDaoImpl is annotated with @Repository @Repository public class UserDaoImpl extends GenericDaoJpa implements UserDao { &#8230; @Override public void saveUser(User user) throws Exception{ entityManager.persist(user); } &#8230; } My app-data.xml is as follow: Now, in my jUnit test method, I deliberately insert a duplicate object and I got javax.persistence.PersistenceException instead of a spring exception. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-3057","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/3057","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/comments?post=3057"}],"version-history":[{"count":0,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/3057\/revisions"}],"wp:attachment":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/media?parent=3057"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/categories?post=3057"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/tags?post=3057"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}