7

I'm trying to handle unique key constraint violations in a Spring + JPA + Hibernate environment.

I use PersistenceExceptionTranslationPostProcessor to translate a PersistenceException to a DataAccessException. When there's a unique key constraint violation, I'd expect a DuplicateKeyException or a DataIntegrityViolationException thrown, but all I get is a JpaSystemException that wraps a PersistenceException.

Isn't the whole point of using the DataAccessException hierarchy that it's fine-grained enough not to have to look up the vendor-specific error code?

How do I have Spring translate a PersistenceException to a more specific DataAccessException ?

EDIT: I noticed that this.jpaDialect in DataAccessUtils.translateIfNecessary() is null. Is there some setting I need to configure to set this.jpaDialect to HibernateJpaDialect?

Thanks!

Tom Tucker
  • 11,676
  • 22
  • 89
  • 130
  • Have you tried with @Repository annotation over DAO class? If so, what exception is thrown when it is not used? – Tomasz Nurkiewicz Feb 25 '11 at 19:33
  • @Tomasz Yeah, Spring does translate PersistenceException's, but to a JpaSystemException which isn't specific enough. Without translation, a PersistenceException is thrown. – Tom Tucker Feb 25 '11 at 19:59
  • Can you try adding breakpoint in `org.springframework.orm.jpa.vendor.HibernateJpaDialect#translateExceptionIfPossible` method to see how Spring translates JDBC/JPA/Hibernate exceptions behind the hood? It would also be great to see how does your complete stack trace look like, especially which exceptions are wrapped. – Tomasz Nurkiewicz Feb 25 '11 at 20:21
  • @Tomasz Execution does not reach the breakpoint. – Tom Tucker Feb 25 '11 at 20:58
  • 1
    This is weird, I just tried it with JPA/Hibernate and this is the place where exceptions are being translated. Could you put the breakpoint earlier in `org.springframework.dao.support.DataAccessUtils#translateIfNecessary`. I suspect you don't have a proper JPA dialect set. Are you sure it is `org.springframework.orm.jpa.vendor.HibernateJpaDialect`? When you reach `org.springframework.orm.jpa.AbstractEntityManagerFactoryBean#translateExceptionIfPossible` with debugger, this dialect should be used for translation, but apparently it is not. – Tomasz Nurkiewicz Feb 25 '11 at 21:22
  • Thanks, I think you're onto something. Control reaches DataAccessUtils#translateIfNecessary but this.jpaDialect is null. Is there some setting I need to configure to set this.jpaDialect to HibernateJpaDialect? – Tom Tucker Feb 25 '11 at 21:46

1 Answers1

9

Apparently you don't have jpaDialect set. For Hibernate it should look like this:

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
    </property>
    <!-- ... -->
</bean>
Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674