So, here's my setup. Let me know if you see something missing.
I'm using AspectJ with compile-time-weaving. The JpaExceptionTranslatorAspect automatically kicks in to perform the translation. For example, here is a stack trace of a domain entity that threw the exception:
Code:
Caused by: org.springframework.orm.jpa.JpaSystemException: org.hibernate.exception.ConstraintViolationException: could not insert: [model.Account]; nested exception is javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not insert: [model.Account]
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:311)
at org.springframework.orm.jpa.aspectj.JpaExceptionTranslatorAspect.ajc$afterThrowing$org_springframework_orm_jpa_aspectj_JpaExceptionTranslatorAspect$1$18a1ac9(JpaExceptionTranslatorAspect.aj:15)
at assets.persistence.repository.GenericDaoImpl.save(GenericDaoImpl.java:64)
at assets.persistence.model.AggregateRoot.save(AggregateRoot.java:21)
at model.Account.submitForRegistration(Account.java:103)
at webui.registration.RegisterForm.onSubmit(RegisterForm.java:158)
at org.apache.wicket.markup.html.form.Form$10.component(Form.java:1164)
at org.apache.wicket.markup.html.form.Form$10.component(Form.java:1159)
at org.apache.wicket.util.visit.Visits.visitPostOrderHelper(Visits.java:276)
at org.apache.wicket.util.visit.Visits.visitPostOrder(Visits.java:247)
at org.apache.wicket.markup.html.form.Form.delegateSubmit(Form.java:1157)
at org.apache.wicket.markup.html.form.Form.process(Form.java:810)
at org.apache.wicket.markup.html.form.Form.onFormSubmitted(Form.java:742)
at org.apache.wicket.markup.html.form.Form.onFormSubmitted(Form.java:684)
... 34 more
My entity manager is configured as follows (I use the HibernateJpaVendorAdapter to indicate that Spring should adjust itself to the Hibernate JPA implementation):
Code:
<bean
id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name=" value="MY_PU" />
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="${database.platform}" />
<property name="showSql" value="${database.showSql}" />
<property name="generateDdl" value="${database.generateDdl}" />
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.ejb.naming_strategy">
org.hibernate.cfg.ImprovedNamingStrategy
</prop>
<prop key="hibernate.hbm2ddl.auto">
${database.hibernate.hbm2ddl}
</prop>
<prop key="hibernate.transaction.manager_lookup_class">
com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup
</prop>
</props>
</property>
</bean>
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
Note that afaik, for AspectJ there is no need to register the "PersistenceExceptionTranslationPostProcessor" as it does not apply to @Configurable classes.
In any case, I tried both with and without it (in the context above it is shown), with the same results.