Introduced local support for Hibernate 3.6 and 4.x exception translation to HibernateJpaDialect
Since Hibernate 3.6 and 4.x differ in exception handling now, this change makes HibernateJpaDialect independent from orm.hibernate3 now and avoids introducing a conditional dependency on orm.hibernate4. Issue: SPR-10815
This commit is contained in:
@@ -36,4 +36,8 @@ public class JpaSystemException extends UncategorizedDataAccessException {
|
||||
super(ex.getMessage(), ex);
|
||||
}
|
||||
|
||||
public JpaSystemException(RuntimeException ex) {
|
||||
super(ex.getMessage(), ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,14 +24,43 @@ import javax.persistence.PersistenceException;
|
||||
|
||||
import org.hibernate.FlushMode;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.NonUniqueObjectException;
|
||||
import org.hibernate.NonUniqueResultException;
|
||||
import org.hibernate.ObjectDeletedException;
|
||||
import org.hibernate.OptimisticLockException;
|
||||
import org.hibernate.PersistentObjectException;
|
||||
import org.hibernate.PessimisticLockException;
|
||||
import org.hibernate.PropertyValueException;
|
||||
import org.hibernate.QueryException;
|
||||
import org.hibernate.QueryTimeoutException;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.StaleObjectStateException;
|
||||
import org.hibernate.StaleStateException;
|
||||
import org.hibernate.TransientObjectException;
|
||||
import org.hibernate.UnresolvableObjectException;
|
||||
import org.hibernate.WrongClassException;
|
||||
import org.hibernate.exception.ConstraintViolationException;
|
||||
import org.hibernate.exception.DataException;
|
||||
import org.hibernate.exception.JDBCConnectionException;
|
||||
import org.hibernate.exception.LockAcquisitionException;
|
||||
import org.hibernate.exception.SQLGrammarException;
|
||||
|
||||
import org.springframework.dao.CannotAcquireLockException;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.dao.IncorrectResultSizeDataAccessException;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.dao.InvalidDataAccessResourceUsageException;
|
||||
import org.springframework.dao.PessimisticLockingFailureException;
|
||||
import org.springframework.jdbc.datasource.ConnectionHandle;
|
||||
import org.springframework.jdbc.support.JdbcUtils;
|
||||
import org.springframework.orm.hibernate3.SessionFactoryUtils;
|
||||
import org.springframework.orm.ObjectOptimisticLockingFailureException;
|
||||
import org.springframework.orm.ObjectRetrievalFailureException;
|
||||
import org.springframework.orm.jpa.DefaultJpaDialect;
|
||||
import org.springframework.orm.jpa.EntityManagerFactoryUtils;
|
||||
import org.springframework.orm.jpa.JpaSystemException;
|
||||
import org.springframework.transaction.TransactionDefinition;
|
||||
import org.springframework.transaction.TransactionException;
|
||||
import org.springframework.util.ClassUtils;
|
||||
@@ -48,6 +77,28 @@ import org.springframework.util.ReflectionUtils;
|
||||
@SuppressWarnings("serial")
|
||||
public class HibernateJpaDialect extends DefaultJpaDialect {
|
||||
|
||||
private static Class<?> optimisticLockExceptionClass;
|
||||
|
||||
private static Class<?> pessimisticLockExceptionClass;
|
||||
|
||||
static {
|
||||
// Checking for Hibernate 4.x's Optimistic/PessimisticEntityLockException
|
||||
ClassLoader cl = HibernateJpaDialect.class.getClassLoader();
|
||||
try {
|
||||
optimisticLockExceptionClass = cl.loadClass("org.hibernate.dialect.lock.OptimisticEntityLockException");
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
optimisticLockExceptionClass = OptimisticLockException.class;
|
||||
}
|
||||
try {
|
||||
pessimisticLockExceptionClass = cl.loadClass("org.hibernate.dialect.lock.PessimisticEntityLockException");
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
pessimisticLockExceptionClass = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object beginTransaction(EntityManager entityManager, TransactionDefinition definition)
|
||||
throws PersistenceException, SQLException, TransactionException {
|
||||
@@ -97,14 +148,101 @@ public class HibernateJpaDialect extends DefaultJpaDialect {
|
||||
@Override
|
||||
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
|
||||
if (ex instanceof HibernateException) {
|
||||
return SessionFactoryUtils.convertHibernateAccessException((HibernateException) ex);
|
||||
return convertHibernateAccessException((HibernateException) ex);
|
||||
}
|
||||
if (ex instanceof PersistenceException && ex.getCause() instanceof HibernateException) {
|
||||
return SessionFactoryUtils.convertHibernateAccessException((HibernateException) ex.getCause());
|
||||
return convertHibernateAccessException((HibernateException) ex.getCause());
|
||||
}
|
||||
return EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(ex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given HibernateException to an appropriate exception
|
||||
* from the {@code org.springframework.dao} hierarchy.
|
||||
* @param ex HibernateException that occurred
|
||||
* @return the corresponding DataAccessException instance
|
||||
*/
|
||||
protected DataAccessException convertHibernateAccessException(HibernateException ex) {
|
||||
if (ex instanceof JDBCConnectionException) {
|
||||
return new DataAccessResourceFailureException(ex.getMessage(), ex);
|
||||
}
|
||||
if (ex instanceof SQLGrammarException) {
|
||||
SQLGrammarException jdbcEx = (SQLGrammarException) ex;
|
||||
return new InvalidDataAccessResourceUsageException(ex.getMessage() + "; SQL [" + jdbcEx.getSQL() + "]", ex);
|
||||
}
|
||||
if (ex instanceof QueryTimeoutException) {
|
||||
QueryTimeoutException jdbcEx = (QueryTimeoutException) ex;
|
||||
return new org.springframework.dao.QueryTimeoutException(ex.getMessage() + "; SQL [" + jdbcEx.getSQL() + "]", ex);
|
||||
}
|
||||
if (ex instanceof LockAcquisitionException) {
|
||||
LockAcquisitionException jdbcEx = (LockAcquisitionException) ex;
|
||||
return new CannotAcquireLockException(ex.getMessage() + "; SQL [" + jdbcEx.getSQL() + "]", ex);
|
||||
}
|
||||
if (ex instanceof PessimisticLockException) {
|
||||
PessimisticLockException jdbcEx = (PessimisticLockException) ex;
|
||||
return new PessimisticLockingFailureException(ex.getMessage() + "; SQL [" + jdbcEx.getSQL() + "]", ex);
|
||||
}
|
||||
if (ex instanceof ConstraintViolationException) {
|
||||
ConstraintViolationException jdbcEx = (ConstraintViolationException) ex;
|
||||
return new DataIntegrityViolationException(ex.getMessage() + "; SQL [" + jdbcEx.getSQL() +
|
||||
"]; constraint [" + jdbcEx.getConstraintName() + "]", ex);
|
||||
}
|
||||
if (ex instanceof DataException) {
|
||||
DataException jdbcEx = (DataException) ex;
|
||||
return new DataIntegrityViolationException(ex.getMessage() + "; SQL [" + jdbcEx.getSQL() + "]", ex);
|
||||
}
|
||||
// end of JDBCException subclass handling
|
||||
|
||||
if (ex instanceof QueryException) {
|
||||
return new InvalidDataAccessResourceUsageException(ex.getMessage(), ex);
|
||||
}
|
||||
if (ex instanceof NonUniqueResultException) {
|
||||
return new IncorrectResultSizeDataAccessException(ex.getMessage(), 1, ex);
|
||||
}
|
||||
if (ex instanceof NonUniqueObjectException) {
|
||||
return new DuplicateKeyException(ex.getMessage(), ex);
|
||||
}
|
||||
if (ex instanceof PropertyValueException) {
|
||||
return new DataIntegrityViolationException(ex.getMessage(), ex);
|
||||
}
|
||||
if (ex instanceof PersistentObjectException) {
|
||||
return new InvalidDataAccessApiUsageException(ex.getMessage(), ex);
|
||||
}
|
||||
if (ex instanceof TransientObjectException) {
|
||||
return new InvalidDataAccessApiUsageException(ex.getMessage(), ex);
|
||||
}
|
||||
if (ex instanceof ObjectDeletedException) {
|
||||
return new InvalidDataAccessApiUsageException(ex.getMessage(), ex);
|
||||
}
|
||||
if (ex instanceof UnresolvableObjectException) {
|
||||
UnresolvableObjectException hibEx = (UnresolvableObjectException) ex;
|
||||
return new ObjectRetrievalFailureException(hibEx.getEntityName(), hibEx.getIdentifier(), ex.getMessage(), ex);
|
||||
}
|
||||
if (ex instanceof WrongClassException) {
|
||||
WrongClassException hibEx = (WrongClassException) ex;
|
||||
return new ObjectRetrievalFailureException(hibEx.getEntityName(), hibEx.getIdentifier(), ex.getMessage(), ex);
|
||||
}
|
||||
if (ex instanceof StaleObjectStateException) {
|
||||
StaleObjectStateException hibEx = (StaleObjectStateException) ex;
|
||||
return new ObjectOptimisticLockingFailureException(hibEx.getEntityName(), hibEx.getIdentifier(), ex);
|
||||
}
|
||||
if (ex instanceof StaleStateException) {
|
||||
return new ObjectOptimisticLockingFailureException(ex.getMessage(), ex);
|
||||
}
|
||||
if (optimisticLockExceptionClass.isInstance(ex)) {
|
||||
return new ObjectOptimisticLockingFailureException(ex.getMessage(), ex);
|
||||
}
|
||||
if (pessimisticLockExceptionClass != null && pessimisticLockExceptionClass.isInstance(ex)) {
|
||||
if (ex.getCause() instanceof LockAcquisitionException) {
|
||||
return new CannotAcquireLockException(ex.getMessage(), ex.getCause());
|
||||
}
|
||||
return new PessimisticLockingFailureException(ex.getMessage(), ex);
|
||||
}
|
||||
|
||||
// fallback
|
||||
return new JpaSystemException(ex);
|
||||
}
|
||||
|
||||
protected Session getSession(EntityManager em) {
|
||||
return em.unwrap(Session.class);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user