diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateTemplate.java b/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateTemplate.java index 601d389ae0a..83b43d4af36 100644 --- a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateTemplate.java +++ b/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateTemplate.java @@ -24,6 +24,7 @@ import java.lang.reflect.Proxy; import java.util.Collection; import java.util.Iterator; import java.util.List; +import javax.persistence.PersistenceException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -357,6 +358,12 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean catch (HibernateException ex) { throw SessionFactoryUtils.convertHibernateAccessException(ex); } + catch (PersistenceException ex) { + if (ex.getCause() instanceof HibernateException) { + throw SessionFactoryUtils.convertHibernateAccessException((HibernateException) ex.getCause()); + } + throw ex; + } catch (RuntimeException ex) { // Callback code threw application exception... throw ex; diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateTransactionManager.java b/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateTransactionManager.java index cafee104658..746d70c24d2 100644 --- a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateTransactionManager.java +++ b/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateTransactionManager.java @@ -18,6 +18,7 @@ package org.springframework.orm.hibernate5; import java.sql.Connection; import java.sql.ResultSet; +import javax.persistence.PersistenceException; import javax.sql.DataSource; import org.hibernate.ConnectionReleaseMode; @@ -588,6 +589,12 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana // assumably failed to flush changes to database throw convertHibernateAccessException(ex); } + catch (PersistenceException ex) { + if (ex.getCause() instanceof HibernateException) { + throw convertHibernateAccessException((HibernateException) ex.getCause()); + } + throw ex; + } } @Override @@ -607,6 +614,12 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana // Shouldn't really happen, as a rollback doesn't cause a flush. throw convertHibernateAccessException(ex); } + catch (PersistenceException ex) { + if (ex.getCause() instanceof HibernateException) { + throw convertHibernateAccessException((HibernateException) ex.getCause()); + } + throw ex; + } finally { if (!txObject.isNewSession() && !this.hibernateManagedSession) { // Clear all pending inserts/updates/deletes in the Session. @@ -825,6 +838,12 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana catch (HibernateException ex) { throw convertHibernateAccessException(ex); } + catch (PersistenceException ex) { + if (ex.getCause() instanceof HibernateException) { + throw convertHibernateAccessException((HibernateException) ex.getCause()); + } + throw ex; + } } } diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SessionFactoryUtils.java b/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SessionFactoryUtils.java index f297f36066f..7f3d2e28a78 100644 --- a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SessionFactoryUtils.java +++ b/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SessionFactoryUtils.java @@ -18,6 +18,7 @@ package org.springframework.orm.hibernate5; import java.lang.reflect.Method; import java.util.Map; +import javax.persistence.PersistenceException; import javax.sql.DataSource; import org.apache.commons.logging.Log; @@ -123,6 +124,37 @@ public abstract class SessionFactoryUtils { return (FlushMode) ReflectionUtils.invokeMethod(getFlushMode, session); } + /** + * Trigger a flush on the given Hibernate Session, converting regular + * {@link HibernateException} instances as well as Hibernate 5.2's + * {@link PersistenceException} wrappers accordingly. + * @param session the Hibernate Session to flush + * @param synch whether this flush is triggered by transaction synchronization + * @throws DataAccessException + * @since 4.3.2 + */ + static void flush(Session session, boolean synch) throws DataAccessException { + if (synch) { + logger.debug("Flushing Hibernate Session on transaction synchronization"); + } + else { + logger.debug("Flushing Hibernate Session on explicit request"); + } + try { + session.flush(); + } + catch (HibernateException ex) { + throw convertHibernateAccessException(ex); + } + catch (PersistenceException ex) { + if (ex.getCause() instanceof HibernateException) { + throw convertHibernateAccessException((HibernateException) ex.getCause()); + } + throw ex; + } + + } + /** * Perform actual closing of the Hibernate Session, * catching and logging any cleanup exceptions thrown. diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SpringFlushSynchronization.java b/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SpringFlushSynchronization.java index b421a4f3740..1c370a00bd1 100644 --- a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SpringFlushSynchronization.java +++ b/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SpringFlushSynchronization.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,6 @@ package org.springframework.orm.hibernate5; -import org.hibernate.HibernateException; import org.hibernate.Session; import org.springframework.transaction.support.TransactionSynchronizationAdapter; @@ -40,13 +39,7 @@ public class SpringFlushSynchronization extends TransactionSynchronizationAdapte @Override public void flush() { - try { - SessionFactoryUtils.logger.debug("Flushing Hibernate Session on explicit request"); - this.session.flush(); - } - catch (HibernateException ex) { - throw SessionFactoryUtils.convertHibernateAccessException(ex); - } + SessionFactoryUtils.flush(this.session, false); } diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SpringSessionSynchronization.java b/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SpringSessionSynchronization.java index 09239e5663e..b806672064b 100644 --- a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SpringSessionSynchronization.java +++ b/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SpringSessionSynchronization.java @@ -17,7 +17,6 @@ package org.springframework.orm.hibernate5; import org.hibernate.FlushMode; -import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.SessionFactory; @@ -83,13 +82,7 @@ public class SpringSessionSynchronization implements TransactionSynchronization, @Override public void flush() { - try { - SessionFactoryUtils.logger.debug("Flushing Hibernate Session on explicit request"); - getCurrentSession().flush(); - } - catch (HibernateException ex) { - throw SessionFactoryUtils.convertHibernateAccessException(ex); - } + SessionFactoryUtils.flush(getCurrentSession(), false); } @Override @@ -99,13 +92,7 @@ public class SpringSessionSynchronization implements TransactionSynchronization, // Read-write transaction -> flush the Hibernate Session. // Further check: only flush when not FlushMode.MANUAL. if (!FlushMode.MANUAL.equals(SessionFactoryUtils.getFlushMode(session))) { - try { - SessionFactoryUtils.logger.debug("Flushing Hibernate Session on transaction synchronization"); - session.flush(); - } - catch (HibernateException ex) { - throw SessionFactoryUtils.convertHibernateAccessException(ex); - } + SessionFactoryUtils.flush(getCurrentSession(), true); } } }