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.Collection;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import javax.persistence.PersistenceException;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
@ -357,6 +358,12 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
|
||||||
catch (HibernateException ex) {
|
catch (HibernateException ex) {
|
||||||
throw SessionFactoryUtils.convertHibernateAccessException(ex);
|
throw SessionFactoryUtils.convertHibernateAccessException(ex);
|
||||||
}
|
}
|
||||||
|
catch (PersistenceException ex) {
|
||||||
|
if (ex.getCause() instanceof HibernateException) {
|
||||||
|
throw SessionFactoryUtils.convertHibernateAccessException((HibernateException) ex.getCause());
|
||||||
|
}
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
catch (RuntimeException ex) {
|
catch (RuntimeException ex) {
|
||||||
// Callback code threw application exception...
|
// Callback code threw application exception...
|
||||||
throw ex;
|
throw ex;
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ package org.springframework.orm.hibernate5;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
|
import javax.persistence.PersistenceException;
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
import org.hibernate.ConnectionReleaseMode;
|
import org.hibernate.ConnectionReleaseMode;
|
||||||
|
|
@ -588,6 +589,12 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
|
||||||
// assumably failed to flush changes to database
|
// assumably failed to flush changes to database
|
||||||
throw convertHibernateAccessException(ex);
|
throw convertHibernateAccessException(ex);
|
||||||
}
|
}
|
||||||
|
catch (PersistenceException ex) {
|
||||||
|
if (ex.getCause() instanceof HibernateException) {
|
||||||
|
throw convertHibernateAccessException((HibernateException) ex.getCause());
|
||||||
|
}
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -607,6 +614,12 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
|
||||||
// Shouldn't really happen, as a rollback doesn't cause a flush.
|
// Shouldn't really happen, as a rollback doesn't cause a flush.
|
||||||
throw convertHibernateAccessException(ex);
|
throw convertHibernateAccessException(ex);
|
||||||
}
|
}
|
||||||
|
catch (PersistenceException ex) {
|
||||||
|
if (ex.getCause() instanceof HibernateException) {
|
||||||
|
throw convertHibernateAccessException((HibernateException) ex.getCause());
|
||||||
|
}
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
finally {
|
finally {
|
||||||
if (!txObject.isNewSession() && !this.hibernateManagedSession) {
|
if (!txObject.isNewSession() && !this.hibernateManagedSession) {
|
||||||
// Clear all pending inserts/updates/deletes in the Session.
|
// Clear all pending inserts/updates/deletes in the Session.
|
||||||
|
|
@ -825,6 +838,12 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
|
||||||
catch (HibernateException ex) {
|
catch (HibernateException ex) {
|
||||||
throw convertHibernateAccessException(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.lang.reflect.Method;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import javax.persistence.PersistenceException;
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
|
|
@ -123,6 +124,37 @@ public abstract class SessionFactoryUtils {
|
||||||
return (FlushMode) ReflectionUtils.invokeMethod(getFlushMode, session);
|
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,
|
* Perform actual closing of the Hibernate Session,
|
||||||
* catching and logging any cleanup exceptions thrown.
|
* 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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
package org.springframework.orm.hibernate5;
|
package org.springframework.orm.hibernate5;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
|
||||||
import org.hibernate.Session;
|
import org.hibernate.Session;
|
||||||
|
|
||||||
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
|
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
|
||||||
|
|
@ -40,13 +39,7 @@ public class SpringFlushSynchronization extends TransactionSynchronizationAdapte
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void flush() {
|
public void flush() {
|
||||||
try {
|
SessionFactoryUtils.flush(this.session, false);
|
||||||
SessionFactoryUtils.logger.debug("Flushing Hibernate Session on explicit request");
|
|
||||||
this.session.flush();
|
|
||||||
}
|
|
||||||
catch (HibernateException ex) {
|
|
||||||
throw SessionFactoryUtils.convertHibernateAccessException(ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@
|
||||||
package org.springframework.orm.hibernate5;
|
package org.springframework.orm.hibernate5;
|
||||||
|
|
||||||
import org.hibernate.FlushMode;
|
import org.hibernate.FlushMode;
|
||||||
import org.hibernate.HibernateException;
|
|
||||||
import org.hibernate.Session;
|
import org.hibernate.Session;
|
||||||
import org.hibernate.SessionFactory;
|
import org.hibernate.SessionFactory;
|
||||||
|
|
||||||
|
|
@ -83,13 +82,7 @@ public class SpringSessionSynchronization implements TransactionSynchronization,
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void flush() {
|
public void flush() {
|
||||||
try {
|
SessionFactoryUtils.flush(getCurrentSession(), false);
|
||||||
SessionFactoryUtils.logger.debug("Flushing Hibernate Session on explicit request");
|
|
||||||
getCurrentSession().flush();
|
|
||||||
}
|
|
||||||
catch (HibernateException ex) {
|
|
||||||
throw SessionFactoryUtils.convertHibernateAccessException(ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -99,13 +92,7 @@ public class SpringSessionSynchronization implements TransactionSynchronization,
|
||||||
// Read-write transaction -> flush the Hibernate Session.
|
// Read-write transaction -> flush the Hibernate Session.
|
||||||
// Further check: only flush when not FlushMode.MANUAL.
|
// Further check: only flush when not FlushMode.MANUAL.
|
||||||
if (!FlushMode.MANUAL.equals(SessionFactoryUtils.getFlushMode(session))) {
|
if (!FlushMode.MANUAL.equals(SessionFactoryUtils.getFlushMode(session))) {
|
||||||
try {
|
SessionFactoryUtils.flush(getCurrentSession(), true);
|
||||||
SessionFactoryUtils.logger.debug("Flushing Hibernate Session on transaction synchronization");
|
|
||||||
session.flush();
|
|
||||||
}
|
|
||||||
catch (HibernateException ex) {
|
|
||||||
throw SessionFactoryUtils.convertHibernateAccessException(ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue