Skip to content

Commit adbc592

Browse files
committed
Unwrap JPA PersistenceException on flush failure (for Hibernate 5.2)
Issue: SPR-14457
1 parent ddb4117 commit adbc592

File tree

5 files changed

+62
-24
lines changed

5 files changed

+62
-24
lines changed

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.util.Collection;
2525
import java.util.Iterator;
2626
import java.util.List;
27+
import javax.persistence.PersistenceException;
2728

2829
import org.apache.commons.logging.Log;
2930
import org.apache.commons.logging.LogFactory;
@@ -357,6 +358,12 @@ protected <T> T doExecute(HibernateCallback<T> action, boolean enforceNativeSess
357358
catch (HibernateException ex) {
358359
throw SessionFactoryUtils.convertHibernateAccessException(ex);
359360
}
361+
catch (PersistenceException ex) {
362+
if (ex.getCause() instanceof HibernateException) {
363+
throw SessionFactoryUtils.convertHibernateAccessException((HibernateException) ex.getCause());
364+
}
365+
throw ex;
366+
}
360367
catch (RuntimeException ex) {
361368
// Callback code threw application exception...
362369
throw ex;

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.sql.Connection;
2020
import java.sql.ResultSet;
21+
import javax.persistence.PersistenceException;
2122
import javax.sql.DataSource;
2223

2324
import org.hibernate.ConnectionReleaseMode;
@@ -588,6 +589,12 @@ protected void doCommit(DefaultTransactionStatus status) {
588589
// assumably failed to flush changes to database
589590
throw convertHibernateAccessException(ex);
590591
}
592+
catch (PersistenceException ex) {
593+
if (ex.getCause() instanceof HibernateException) {
594+
throw convertHibernateAccessException((HibernateException) ex.getCause());
595+
}
596+
throw ex;
597+
}
591598
}
592599

593600
@Override
@@ -607,6 +614,12 @@ protected void doRollback(DefaultTransactionStatus status) {
607614
// Shouldn't really happen, as a rollback doesn't cause a flush.
608615
throw convertHibernateAccessException(ex);
609616
}
617+
catch (PersistenceException ex) {
618+
if (ex.getCause() instanceof HibernateException) {
619+
throw convertHibernateAccessException((HibernateException) ex.getCause());
620+
}
621+
throw ex;
622+
}
610623
finally {
611624
if (!txObject.isNewSession() && !this.hibernateManagedSession) {
612625
// Clear all pending inserts/updates/deletes in the Session.
@@ -825,6 +838,12 @@ public void flush() {
825838
catch (HibernateException ex) {
826839
throw convertHibernateAccessException(ex);
827840
}
841+
catch (PersistenceException ex) {
842+
if (ex.getCause() instanceof HibernateException) {
843+
throw convertHibernateAccessException((HibernateException) ex.getCause());
844+
}
845+
throw ex;
846+
}
828847
}
829848
}
830849

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

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.lang.reflect.Method;
2020
import java.util.Map;
21+
import javax.persistence.PersistenceException;
2122
import javax.sql.DataSource;
2223

2324
import org.apache.commons.logging.Log;
@@ -123,6 +124,37 @@ static FlushMode getFlushMode(Session session) {
123124
return (FlushMode) ReflectionUtils.invokeMethod(getFlushMode, session);
124125
}
125126

127+
/**
128+
* Trigger a flush on the given Hibernate Session, converting regular
129+
* {@link HibernateException} instances as well as Hibernate 5.2's
130+
* {@link PersistenceException} wrappers accordingly.
131+
* @param session the Hibernate Session to flush
132+
* @param synch whether this flush is triggered by transaction synchronization
133+
* @throws DataAccessException
134+
* @since 4.3.2
135+
*/
136+
static void flush(Session session, boolean synch) throws DataAccessException {
137+
if (synch) {
138+
logger.debug("Flushing Hibernate Session on transaction synchronization");
139+
}
140+
else {
141+
logger.debug("Flushing Hibernate Session on explicit request");
142+
}
143+
try {
144+
session.flush();
145+
}
146+
catch (HibernateException ex) {
147+
throw convertHibernateAccessException(ex);
148+
}
149+
catch (PersistenceException ex) {
150+
if (ex.getCause() instanceof HibernateException) {
151+
throw convertHibernateAccessException((HibernateException) ex.getCause());
152+
}
153+
throw ex;
154+
}
155+
156+
}
157+
126158
/**
127159
* Perform actual closing of the Hibernate Session,
128160
* catching and logging any cleanup exceptions thrown.

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

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2015 the original author or authors.
2+
* Copyright 2002-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
1616

1717
package org.springframework.orm.hibernate5;
1818

19-
import org.hibernate.HibernateException;
2019
import org.hibernate.Session;
2120

2221
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
@@ -40,13 +39,7 @@ public SpringFlushSynchronization(Session session) {
4039

4140
@Override
4241
public void flush() {
43-
try {
44-
SessionFactoryUtils.logger.debug("Flushing Hibernate Session on explicit request");
45-
this.session.flush();
46-
}
47-
catch (HibernateException ex) {
48-
throw SessionFactoryUtils.convertHibernateAccessException(ex);
49-
}
42+
SessionFactoryUtils.flush(this.session, false);
5043
}
5144

5245

spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringSessionSynchronization.java

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package org.springframework.orm.hibernate5;
1818

1919
import org.hibernate.FlushMode;
20-
import org.hibernate.HibernateException;
2120
import org.hibernate.Session;
2221
import org.hibernate.SessionFactory;
2322

@@ -83,13 +82,7 @@ public void resume() {
8382

8483
@Override
8584
public void flush() {
86-
try {
87-
SessionFactoryUtils.logger.debug("Flushing Hibernate Session on explicit request");
88-
getCurrentSession().flush();
89-
}
90-
catch (HibernateException ex) {
91-
throw SessionFactoryUtils.convertHibernateAccessException(ex);
92-
}
85+
SessionFactoryUtils.flush(getCurrentSession(), false);
9386
}
9487

9588
@Override
@@ -99,13 +92,7 @@ public void beforeCommit(boolean readOnly) throws DataAccessException {
9992
// Read-write transaction -> flush the Hibernate Session.
10093
// Further check: only flush when not FlushMode.MANUAL.
10194
if (!FlushMode.MANUAL.equals(SessionFactoryUtils.getFlushMode(session))) {
102-
try {
103-
SessionFactoryUtils.logger.debug("Flushing Hibernate Session on transaction synchronization");
104-
session.flush();
105-
}
106-
catch (HibernateException ex) {
107-
throw SessionFactoryUtils.convertHibernateAccessException(ex);
108-
}
95+
SessionFactoryUtils.flush(getCurrentSession(), true);
10996
}
11097
}
11198
}

0 commit comments

Comments
 (0)