This forum is now a read-only archive. All commenting, posting, registration services have been turned off. Those needing community support and/or wanting to ask questions should refer to the Tag/Forum map, and to http://spring.io/questions for a curated list of stackoverflow tags that Pivotal engineers, and the community, monitor.

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.

Comment

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.

Comment

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.

Comment

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?

Comment

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

Comment

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.

Comment

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.

Comment

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.

Hi,

If OpenJPA were throwing an org.apache.openjpa.persistence.ReferentialIntegrit yException instead of just a PersistenceException, would that change things?

-Patrick

Comment

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.

Hi,

Yes, I understand the value of Spring's exception translation facilities. I'm wondering more about implementation details. Since OpenJPA already translates 100% of the exceptions thrown (including exceptions thrown from within lazy loading and such from direct access of persistent data in a managed instance), it would seem that we could do a more optimal integration between Spring and OpenJPA, such that OpenJPA translated exceptions directly from OpenJPA-internal types to Spring types, instead of the current OpenJPA-internal => JPA spec + extensions => Spring types.

Does that make sense?

-Patrick

Comment

Yes, I understand the value of Spring's exception translation facilities. I'm wondering more about implementation details. Since OpenJPA already translates 100% of the exceptions thrown (including exceptions thrown from within lazy loading and such from direct access of persistent data in a managed instance), it would seem that we could do a more optimal integration between Spring and OpenJPA, such that OpenJPA translated exceptions directly from OpenJPA-internal types to Spring types, instead of the current OpenJPA-internal => JPA spec + extensions => Spring types.

Yes, we could translate any OpenJPA specific exceptions in the OpenJpaDialect class. That would definitely be valuable.

If OpenJPA were throwing an org.apache.openjpa.persistence.ReferentialIntegrit yException instead of just a PersistenceException, would that change things?

That would work with the above scenario and we could translate that directly into a DataIntegrityViolationException.