Browse Source

Unwrap JPA PersistenceException on flush failure (for Hibernate 5.2)

Issue: SPR-14457
pull/1405/head
Juergen Hoeller 10 years ago
parent
commit
29f980ec72
  1. 7
      spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateTemplate.java
  2. 19
      spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateTransactionManager.java
  3. 32
      spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SessionFactoryUtils.java
  4. 11
      spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SpringFlushSynchronization.java
  5. 17
      spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SpringSessionSynchronization.java

7
spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateTemplate.java

@ -24,6 +24,7 @@ import java.lang.reflect.Proxy; @@ -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 @@ -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;

19
spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateTransactionManager.java

@ -18,6 +18,7 @@ package org.springframework.orm.hibernate5; @@ -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 @@ -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 @@ -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 @@ -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;
}
}
}

32
spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SessionFactoryUtils.java

@ -18,6 +18,7 @@ package org.springframework.orm.hibernate5; @@ -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 { @@ -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.

11
spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SpringFlushSynchronization.java

@ -1,5 +1,5 @@ @@ -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 @@ @@ -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 @@ -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
spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SpringSessionSynchronization.java

@ -17,7 +17,6 @@ @@ -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, @@ -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, @@ -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…
Cancel
Save