Unwrap JPA PersistenceException on flush failure (for Hibernate 5.2)
Issue: SPR-14457
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user