Page 1 of 2 12 LastLast
Results 1 to 10 of 13

Thread: JPA ExceptionTranslation issue-Not Translating PersistenceException:unique constrait

  1. #1
    Join Date
    Sep 2007
    Posts
    7

    Default JPA ExceptionTranslation issue-Not Translating PersistenceException:unique constrait

    I am using Spring 2.0.6 and OpenJPA 1.0.My Spring application context is configured to use the PersistenceExceptionTranslationPostProcessor and all DAO classes marked with the @Repository annotation.
    The issue I have is,
    I am trying to create a new Entity with a same field value as another Entity of the same type in the database, the field has a Unique Constraint on it.
    When i do entityManager.persist(entity) i only get a org.apache.openjpa.persistence.PersistenceExceptio n:ORA-00001 unique constrait violated..... and this exception is not translated to spring's DataAccessException.
    I was hoping it to be translated to the DataIntegrityViolated Exception.
    Though some other exceptions are successfully translated to Spring Exceptions I am not sure why the unique constraint violation is not translated.

    Is any one seeing similar issue or have any possible solutions ?
    Your help will be greatly appreciated.
    Last edited by addy999; Sep 20th, 2007 at 12:36 PM.

  2. #2
    Join Date
    Aug 2004
    Posts
    1,110

    Default

    There was an issue where the exception was wrapped with a BatchSQLException. This has been fixed in the 2.1 branch - could you try 2.1m4 and see if you see any change in behavior.
    Thomas Risberg
    SpringSource by Pivotal
    http://www.springsource.org

  3. #3
    Join Date
    Sep 2007
    Posts
    7

    Red face

    Thanks for your reply trisberg.
    I tried with Spring 2.1M4 but get the same issue.

  4. #4
    Join Date
    Aug 2004
    Posts
    1,110

    Default

    Can you post a stacktrace (call printStackTrace on the exception you get)
    Thomas Risberg
    SpringSource by Pivotal
    http://www.springsource.org

  5. #5
    Join Date
    Sep 2007
    Posts
    7

    Default

    Actually, the translateExceptionIfPossible(RuntimeException ex) method of the PersistenceExceptionTranslator interface and implemented by the LocalContainerEntityManagerFactoryBean is not invoked at all for the exception below.
    My application context has the bean defined,
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerE ntityManagerFactoryBean">
    I would expect the PersistenceExceptionTranslationPostProcessor to invoke the translateExceptionIfPossible() method but it does not do it only for this exception.Other exceptions i get are translated through the translateExceptionIfPossible method.I tested this by extending the LocalContainerEntityManagerFactoryBean and overriding the translateExceptionIfPossible() method.While debugging, this method was not invoked at all for the exception below.
    If I manually catch the exception and invoke the EntityManagerFactoryUtils.convertJpaAccessExceptio nIfPossible(RuntimeException ex) then i get a JpaSystemException.
    So the 2 issues now are,
    1.Why i the persistence exception not translated at all ? That is the translateIfPossible() method is not invoked.
    2.When i translate the exception using the EntityManagerFactoryUtils.convertJpaAccessExceptio nIfPossible i get the JpaSystemException instead of some finegrained DataAccessException.


    Below is the Stack Trace,
    <openjpa-0.0.0-r420667:568756 fatal general error> org.apache.openjpa.persistence.PersistenceExceptio n: The transaction has been rolled back. See the nested exceptions for details on the errors that occurred.
    at org.apache.openjpa.kernel.BrokerImpl.newFlushExcep tion(BrokerImpl.java:2099)
    at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerI mpl.java:1946)
    at org.apache.openjpa.kernel.BrokerImpl.flushSafe(Bro kerImpl.java:1844)
    at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerI mpl.java:1615)
    at org.apache.openjpa.kernel.DelegatingBroker.flush(D elegatingBroker.java:973)
    at org.apache.openjpa.persistence.EntityManagerImpl.f lush(EntityManagerImpl.java:488)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Native MethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:25)
    at org.springframework.orm.jpa.SharedEntityManagerCre ator$SharedEntityManagerInvocationHandler.invoke(S haredEntityManagerCreator.java:193)
    at $Proxy30.flush(Unknown Source)
    at com.dao.DAOTest.testCreateEntity(DAOTest.java:90)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Native MethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:25)
    at org.springframework.test.ConditionalTestCase.runBa re(ConditionalTestCase.java:69)
    at org.springframework.test.annotation.AbstractAnnota tionAwareTransactionalTests.access$001(AbstractAnn otationAwareTransactionalTests.java:68)
    at org.springframework.test.annotation.AbstractAnnota tionAwareTransactionalTests$1.run(AbstractAnnotati onAwareTransactionalTests.java:138)
    at org.springframework.test.annotation.AbstractAnnota tionAwareTransactionalTests.runTest(AbstractAnnota tionAwareTransactionalTests.java:258)
    at org.springframework.test.annotation.AbstractAnnota tionAwareTransactionalTests.runTestTimed(AbstractA nnotationAwareTransactionalTests.java:230)
    at org.springframework.test.annotation.AbstractAnnota tionAwareTransactionalTests.runBare(AbstractAnnota tionAwareTransactionalTests.java:133)
    at org.springframework.test.jpa.AbstractJpaTests.runB are(AbstractJpaTests.java:174)
    at org.springframework.test.jpa.AbstractJpaTests.runB are(AbstractJpaTests.java:254)
    at com.intellij.rt.execution.junit.JUnitStarter.main( JUnitStarter.java:40)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Native MethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:25)
    at com.intellij.rt.execution.application.AppMain.main (AppMain.java:90)
    Caused by: <openjpa-0.0.0-r420667:568756 nonfatal general error> org.apache.openjpa.persistence.PersistenceExceptio n: ORA-00001: unique constraint (NAME_UNQ) violated
    {prepstmnt 28394800 INSERT INTO table (id, name, version) VALUES (?, ?, ?, ?) [params=(long) 190, (String) TestName, (int) 1]} [code=1, state=23000]

    at org.apache.openjpa.jdbc.sql.DBDictionary.newStoreE xception(DBDictionary.java:3847)
    at org.apache.openjpa.jdbc.sql.SQLExceptions.getStore (SQLExceptions.java:97)
    at org.apache.openjpa.jdbc.sql.SQLExceptions.getStore (SQLExceptions.java:67)
    at org.apache.openjpa.jdbc.kernel.PreparedStatementMa nagerImpl.flushInternal(PreparedStatementManagerIm pl.java:108)
    at org.apache.openjpa.jdbc.kernel.PreparedStatementMa nagerImpl.flush(PreparedStatementManagerImpl.java: 73)
    at org.apache.openjpa.jdbc.kernel.ConstraintUpdateMan ager.flush(ConstraintUpdateManager.java:543)
    at org.apache.openjpa.jdbc.kernel.ConstraintUpdateMan ager.flush(ConstraintUpdateManager.java:105)
    at org.apache.openjpa.jdbc.kernel.AbstractUpdateManag er.flush(AbstractUpdateManager.java:89)
    at org.apache.openjpa.jdbc.kernel.AbstractUpdateManag er.flush(AbstractUpdateManager.java:72)
    at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.fl ush(JDBCStoreManager.java:514)
    at org.apache.openjpa.kernel.DelegatingStoreManager.f lush(DelegatingStoreManager.java:130)
    ... 45 more
    Caused by: org.apache.openjpa.lib.jdbc.ReportingSQLException: ORA-00001: unique constraint (MMS.DATA_SOURCE_NAME_UNQ) violated
    {prepstmnt 28394800 INSERT INTO data_source (id, last_updated_by, name, version) VALUES (?, ?, ?, ?) [params=(long) 190, (String) User1, (String) DataSource1, (int) 1]} [code=1, state=23000]
    at org.apache.openjpa.lib.jdbc.LoggingConnectionDecor ator.wrap(LoggingConnectionDecorator.java:192)
    at org.apache.openjpa.lib.jdbc.LoggingConnectionDecor ator.access$800(LoggingConnectionDecorator.java:57 )
    at org.apache.openjpa.lib.jdbc.LoggingConnectionDecor ator$LoggingConnection$LoggingPreparedStatement.ex ecuteUpdate(LoggingConnectionDecorator.java:858)
    at org.apache.openjpa.lib.jdbc.DelegatingPreparedStat ement.executeUpdate(DelegatingPreparedStatement.ja va:269)
    at org.apache.openjpa.jdbc.kernel.JDBCStoreManager$Ca ncelPreparedStatement.executeUpdate(JDBCStoreManag er.java:1363)
    at org.apache.openjpa.jdbc.kernel.PreparedStatementMa nagerImpl.flushInternal(PreparedStatementManagerIm pl.java:97)
    ... 52 more

    Thanks for looking into this.

  6. #6
    Join Date
    Sep 2007
    Posts
    7

    Default

    So the issue
    1.Why i the persistence exception not translated at all ? That is the translateIfPossible() method is not invoked.
    is resolved.I was hoping for the exception to be translated but i was flushing my persistent context in the TestCase method i created.If i call the dao.flush() and the dao has @Repository the exception is translated to a JPASystemException.
    The issue still pending is that why does not Spring translate
    org.apache.openjpa.lib.jdbc.ReportingSQLException: ORA-00001: unique constraint exceptions to some DataAccessException instead of the JPASystemException.

  7. #7
    Join Date
    Aug 2004
    Posts
    1,110

    Default

    Looks like you are getting an org.apache.openjpa.persistence.PersistenceExceptio n rather than an EntityExistsException from OpenJPA. If you got the latter it would have been translated to a DataIntegrityViolationException. So why is OpenJPA throwing the more general exception?
    Thomas Risberg
    SpringSource by Pivotal
    http://www.springsource.org

  8. #8
    Join Date
    Aug 2007
    Posts
    11

    Default

    Hi,

    From the description, it doesn't sound like this should be an EntityExistsException. Is there any more indication indicating that the unique constraint violation is due to a PK constraint violation, vs. some other sort of unique constraint?

    FWIW, org.apache.openjpa.persistence.PersistenceExceptio n extends javax.persistence.PersistenceException. Ideally, the Spring code should use translate all exceptions that are instanceof PersistenceException, no?

    Incidentally, OpenJPA has its own exception translation capabilities -- what would be the value of plugging a new SpringExceptionTranslator into OpenJPA when deployed appropriately?

    -Patrick

  9. #9
    Join Date
    Aug 2004
    Posts
    1,110

    Default

    Patrick,

    Re-reading the original description I believe you are correct, this is a unique constraint violation on a non id field. This type of issue doesn't have a specific JPA exception so a general PersistenceException is the closest fit.

    In this case there isn't much we can do without looking at the wrapped SQLException. We aren't doing that since the exception translator doesn't know the underlying database and won't be able to interpret the error code. So the best we can do is to translate to a generic "unknown" type exception in the Spring exception hierarchy which is JpaSystemException.
    Thomas Risberg
    SpringSource by Pivotal
    http://www.springsource.org

  10. #10
    Join Date
    Aug 2004
    Posts
    1,110

    Default

    Incidentally, OpenJPA has its own exception translation capabilities -- what would be the value of plugging a new SpringExceptionTranslator into OpenJPA when deployed appropriately?
    Spring's exception translation sits on top of JPA at the DAO or Repository level and is optional. The benefit is that your service layer only have to deal with exceptions from a single exception hierarchy -- Spring's DataAccessException hierarchy -- regardless of the underlying data access technology. This is definitely valuable when you mix JDBC and ORM in the DAO layer.
    Thomas Risberg
    SpringSource by Pivotal
    http://www.springsource.org

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •