Unwrap JPA PersistenceException on flush failure (for Hibernate 5.2)
Issue: SPR-14457
This commit is contained in:
		
							parent
							
								
									1d39d762f0
								
							
						
					
					
						commit
						29f980ec72
					
				|  | @ -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; | ||||
|  |  | |||
|  | @ -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; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
|  | @ -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. | ||||
|  |  | |||
|  | @ -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); | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -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); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue