Support for Hibernate ORM 5.2

Issue: SPR-14327
This commit is contained in:
Juergen Hoeller 2016-06-02 23:35:31 +02:00
parent 521c41d75e
commit 9394616f8f
13 changed files with 134 additions and 63 deletions

View File

@ -46,7 +46,7 @@ configure(allprojects) { project ->
ext.hamcrestVersion = "1.3" ext.hamcrestVersion = "1.3"
ext.hibernate3Version = "3.6.10.Final" ext.hibernate3Version = "3.6.10.Final"
ext.hibernate4Version = "4.3.11.Final" ext.hibernate4Version = "4.3.11.Final"
ext.hibernate5Version = "5.1.0.Final" ext.hibernate5Version = "5.2.0.Final"
ext.hibval4Version = "4.3.2.Final" ext.hibval4Version = "4.3.2.Final"
ext.hibval5Version = "5.2.4.Final" ext.hibval5Version = "5.2.4.Final"
ext.hsqldbVersion = "2.3.4" ext.hsqldbVersion = "2.3.4"
@ -798,7 +798,6 @@ project("spring-orm-hibernate5") {
provided(project(":spring-tx")) provided(project(":spring-tx"))
optional(project(":spring-web")) optional(project(":spring-web"))
optional("org.hibernate:hibernate-core:${hibernate5Version}") optional("org.hibernate:hibernate-core:${hibernate5Version}")
optional("org.hibernate:hibernate-entitymanager:${hibernate5Version}")
optional("javax.servlet:javax.servlet-api:3.0.1") optional("javax.servlet:javax.servlet-api:3.0.1")
optional("javax.transaction:javax.transaction-api:${jtaVersion}") optional("javax.transaction:javax.transaction-api:${jtaVersion}")
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2014 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.
@ -480,7 +480,7 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
if (!definition.isReadOnly() && !txObject.isNewSession()) { if (!definition.isReadOnly() && !txObject.isNewSession()) {
// We need AUTO or COMMIT for a non-read-only transaction. // We need AUTO or COMMIT for a non-read-only transaction.
FlushMode flushMode = session.getFlushMode(); FlushMode flushMode = session.getFlushMode();
if (session.getFlushMode().equals(FlushMode.MANUAL)) { if (FlushMode.MANUAL.equals(flushMode)) {
session.setFlushMode(FlushMode.AUTO); session.setFlushMode(FlushMode.AUTO);
txObject.getSessionHolder().setPreviousFlushMode(flushMode); txObject.getSessionHolder().setPreviousFlushMode(flushMode);
} }

View File

@ -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.
@ -27,7 +27,6 @@ import java.util.List;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria; import org.hibernate.Criteria;
import org.hibernate.Filter; import org.hibernate.Filter;
import org.hibernate.FlushMode; import org.hibernate.FlushMode;
@ -35,7 +34,6 @@ import org.hibernate.Hibernate;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.LockMode; import org.hibernate.LockMode;
import org.hibernate.LockOptions; import org.hibernate.LockOptions;
import org.hibernate.Query;
import org.hibernate.ReplicationMode; import org.hibernate.ReplicationMode;
import org.hibernate.Session; import org.hibernate.Session;
import org.hibernate.SessionFactory; import org.hibernate.SessionFactory;
@ -211,7 +209,7 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
* <p>To specify the query region to be used for queries cached * <p>To specify the query region to be used for queries cached
* by this template, set the "queryCacheRegion" property. * by this template, set the "queryCacheRegion" property.
* @see #setQueryCacheRegion * @see #setQueryCacheRegion
* @see Query#setCacheable * @see org.hibernate.Query#setCacheable
* @see Criteria#setCacheable * @see Criteria#setCacheable
*/ */
public void setCacheQueries(boolean cacheQueries) { public void setCacheQueries(boolean cacheQueries) {
@ -232,7 +230,7 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
* <p>The cache region will not take effect unless queries created by this * <p>The cache region will not take effect unless queries created by this
* template are configured to be cached via the "cacheQueries" property. * template are configured to be cached via the "cacheQueries" property.
* @see #setCacheQueries * @see #setCacheQueries
* @see Query#setCacheRegion * @see org.hibernate.Query#setCacheRegion
* @see Criteria#setCacheRegion * @see Criteria#setCacheRegion
*/ */
public void setQueryCacheRegion(String queryCacheRegion) { public void setQueryCacheRegion(String queryCacheRegion) {
@ -317,6 +315,7 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
* @return a result object returned by the action, or {@code null} * @return a result object returned by the action, or {@code null}
* @throws DataAccessException in case of Hibernate errors * @throws DataAccessException in case of Hibernate errors
*/ */
@SuppressWarnings("deprecation")
protected <T> T doExecute(HibernateCallback<T> action, boolean enforceNativeSession) throws DataAccessException { protected <T> T doExecute(HibernateCallback<T> action, boolean enforceNativeSession) throws DataAccessException {
Assert.notNull(action, "Callback object must not be null"); Assert.notNull(action, "Callback object must not be null");
@ -499,7 +498,7 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
public <T> List<T> loadAll(final Class<T> entityClass) throws DataAccessException { public <T> List<T> loadAll(final Class<T> entityClass) throws DataAccessException {
return executeWithNativeSession(new HibernateCallback<List<T>>() { return executeWithNativeSession(new HibernateCallback<List<T>>() {
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings({"unchecked", "deprecation"})
public List<T> doInHibernate(Session session) throws HibernateException { public List<T> doInHibernate(Session session) throws HibernateException {
Criteria criteria = session.createCriteria(entityClass); Criteria criteria = session.createCriteria(entityClass);
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
@ -862,8 +861,9 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
public List<?> find(final String queryString, final Object... values) throws DataAccessException { public List<?> find(final String queryString, final Object... values) throws DataAccessException {
return executeWithNativeSession(new HibernateCallback<List<?>>() { return executeWithNativeSession(new HibernateCallback<List<?>>() {
@Override @Override
@SuppressWarnings({"rawtypes", "deprecation"})
public List<?> doInHibernate(Session session) throws HibernateException { public List<?> doInHibernate(Session session) throws HibernateException {
Query queryObject = session.createQuery(queryString); org.hibernate.Query queryObject = session.createQuery(queryString);
prepareQuery(queryObject); prepareQuery(queryObject);
if (values != null) { if (values != null) {
for (int i = 0; i < values.length; i++) { for (int i = 0; i < values.length; i++) {
@ -891,13 +891,12 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
} }
return executeWithNativeSession(new HibernateCallback<List<?>>() { return executeWithNativeSession(new HibernateCallback<List<?>>() {
@Override @Override
@SuppressWarnings({"rawtypes", "deprecation"})
public List<?> doInHibernate(Session session) throws HibernateException { public List<?> doInHibernate(Session session) throws HibernateException {
Query queryObject = session.createQuery(queryString); org.hibernate.Query queryObject = session.createQuery(queryString);
prepareQuery(queryObject); prepareQuery(queryObject);
if (values != null) { for (int i = 0; i < values.length; i++) {
for (int i = 0; i < values.length; i++) { applyNamedParameterToQuery(queryObject, paramNames[i], values[i]);
applyNamedParameterToQuery(queryObject, paramNames[i], values[i]);
}
} }
return queryObject.list(); return queryObject.list();
} }
@ -910,8 +909,9 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
return executeWithNativeSession(new HibernateCallback<List<?>>() { return executeWithNativeSession(new HibernateCallback<List<?>>() {
@Override @Override
@SuppressWarnings({"rawtypes", "deprecation"})
public List<?> doInHibernate(Session session) throws HibernateException { public List<?> doInHibernate(Session session) throws HibernateException {
Query queryObject = session.createQuery(queryString); org.hibernate.Query queryObject = session.createQuery(queryString);
prepareQuery(queryObject); prepareQuery(queryObject);
queryObject.setProperties(valueBean); queryObject.setProperties(valueBean);
return queryObject.list(); return queryObject.list();
@ -928,8 +928,9 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
public List<?> findByNamedQuery(final String queryName, final Object... values) throws DataAccessException { public List<?> findByNamedQuery(final String queryName, final Object... values) throws DataAccessException {
return executeWithNativeSession(new HibernateCallback<List<?>>() { return executeWithNativeSession(new HibernateCallback<List<?>>() {
@Override @Override
@SuppressWarnings({"rawtypes", "deprecation"})
public List<?> doInHibernate(Session session) throws HibernateException { public List<?> doInHibernate(Session session) throws HibernateException {
Query queryObject = session.getNamedQuery(queryName); org.hibernate.Query queryObject = session.getNamedQuery(queryName);
prepareQuery(queryObject); prepareQuery(queryObject);
if (values != null) { if (values != null) {
for (int i = 0; i < values.length; i++) { for (int i = 0; i < values.length; i++) {
@ -958,8 +959,9 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
} }
return executeWithNativeSession(new HibernateCallback<List<?>>() { return executeWithNativeSession(new HibernateCallback<List<?>>() {
@Override @Override
@SuppressWarnings({"rawtypes", "deprecation"})
public List<?> doInHibernate(Session session) throws HibernateException { public List<?> doInHibernate(Session session) throws HibernateException {
Query queryObject = session.getNamedQuery(queryName); org.hibernate.Query queryObject = session.getNamedQuery(queryName);
prepareQuery(queryObject); prepareQuery(queryObject);
if (values != null) { if (values != null) {
for (int i = 0; i < values.length; i++) { for (int i = 0; i < values.length; i++) {
@ -977,8 +979,9 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
return executeWithNativeSession(new HibernateCallback<List<?>>() { return executeWithNativeSession(new HibernateCallback<List<?>>() {
@Override @Override
@SuppressWarnings({"rawtypes", "deprecation"})
public List<?> doInHibernate(Session session) throws HibernateException { public List<?> doInHibernate(Session session) throws HibernateException {
Query queryObject = session.getNamedQuery(queryName); org.hibernate.Query queryObject = session.getNamedQuery(queryName);
prepareQuery(queryObject); prepareQuery(queryObject);
queryObject.setProperties(valueBean); queryObject.setProperties(valueBean);
return queryObject.list(); return queryObject.list();
@ -1033,6 +1036,7 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
} }
@Override @Override
@SuppressWarnings("deprecation")
public <T> List<T> findByExample( public <T> List<T> findByExample(
final String entityName, final T exampleEntity, final int firstResult, final int maxResults) final String entityName, final T exampleEntity, final int firstResult, final int maxResults)
throws DataAccessException { throws DataAccessException {
@ -1066,8 +1070,9 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
public Iterator<?> iterate(final String queryString, final Object... values) throws DataAccessException { public Iterator<?> iterate(final String queryString, final Object... values) throws DataAccessException {
return executeWithNativeSession(new HibernateCallback<Iterator<?>>() { return executeWithNativeSession(new HibernateCallback<Iterator<?>>() {
@Override @Override
@SuppressWarnings({"rawtypes", "deprecation"})
public Iterator<?> doInHibernate(Session session) throws HibernateException { public Iterator<?> doInHibernate(Session session) throws HibernateException {
Query queryObject = session.createQuery(queryString); org.hibernate.Query queryObject = session.createQuery(queryString);
prepareQuery(queryObject); prepareQuery(queryObject);
if (values != null) { if (values != null) {
for (int i = 0; i < values.length; i++) { for (int i = 0; i < values.length; i++) {
@ -1093,8 +1098,9 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
public int bulkUpdate(final String queryString, final Object... values) throws DataAccessException { public int bulkUpdate(final String queryString, final Object... values) throws DataAccessException {
return executeWithNativeSession(new HibernateCallback<Integer>() { return executeWithNativeSession(new HibernateCallback<Integer>() {
@Override @Override
@SuppressWarnings({"rawtypes", "deprecation"})
public Integer doInHibernate(Session session) throws HibernateException { public Integer doInHibernate(Session session) throws HibernateException {
Query queryObject = session.createQuery(queryString); org.hibernate.Query queryObject = session.createQuery(queryString);
prepareQuery(queryObject); prepareQuery(queryObject);
if (values != null) { if (values != null) {
for (int i = 0; i < values.length; i++) { for (int i = 0; i < values.length; i++) {
@ -1122,7 +1128,7 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
* @see FlushMode#MANUAL * @see FlushMode#MANUAL
*/ */
protected void checkWriteOperationAllowed(Session session) throws InvalidDataAccessApiUsageException { protected void checkWriteOperationAllowed(Session session) throws InvalidDataAccessApiUsageException {
if (isCheckWriteOperations() && session.getFlushMode().lessThan(FlushMode.COMMIT)) { if (isCheckWriteOperations() && SessionFactoryUtils.getFlushMode(session).lessThan(FlushMode.COMMIT)) {
throw new InvalidDataAccessApiUsageException( throw new InvalidDataAccessApiUsageException(
"Write operations are not allowed in read-only mode (FlushMode.MANUAL): "+ "Write operations are not allowed in read-only mode (FlushMode.MANUAL): "+
"Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition."); "Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition.");
@ -1136,7 +1142,8 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
* @see #setCacheQueries * @see #setCacheQueries
* @see #setQueryCacheRegion * @see #setQueryCacheRegion
*/ */
protected void prepareQuery(Query queryObject) { @SuppressWarnings({"rawtypes", "deprecation"})
protected void prepareQuery(org.hibernate.Query queryObject) {
if (isCacheQueries()) { if (isCacheQueries()) {
queryObject.setCacheable(true); queryObject.setCacheable(true);
if (getQueryCacheRegion() != null) { if (getQueryCacheRegion() != null) {
@ -1192,7 +1199,8 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
* @param value the value of the parameter * @param value the value of the parameter
* @throws HibernateException if thrown by the Query object * @throws HibernateException if thrown by the Query object
*/ */
protected void applyNamedParameterToQuery(Query queryObject, String paramName, Object value) @SuppressWarnings({"rawtypes", "deprecation"})
protected void applyNamedParameterToQuery(org.hibernate.Query queryObject, String paramName, Object value)
throws HibernateException { throws HibernateException {
if (value instanceof Collection) { if (value instanceof Collection) {
@ -1221,6 +1229,7 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
} }
@Override @Override
@SuppressWarnings("deprecation")
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// Invocation on Session interface coming in... // Invocation on Session interface coming in...
@ -1243,8 +1252,8 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
// If return value is a Query or Criteria, apply transaction timeout. // If return value is a Query or Criteria, apply transaction timeout.
// Applies to createQuery, getNamedQuery, createCriteria. // Applies to createQuery, getNamedQuery, createCriteria.
if (retVal instanceof Query) { if (retVal instanceof org.hibernate.Query) {
prepareQuery(((Query) retVal)); prepareQuery(((org.hibernate.Query) retVal));
} }
if (retVal instanceof Criteria) { if (retVal instanceof Criteria) {
prepareCriteria(((Criteria) retVal)); prepareCriteria(((Criteria) retVal));

View File

@ -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.
@ -412,6 +412,7 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
} }
@Override @Override
@SuppressWarnings("deprecation")
protected void doBegin(Object transaction, TransactionDefinition definition) { protected void doBegin(Object transaction, TransactionDefinition definition) {
HibernateTransactionObject txObject = (HibernateTransactionObject) transaction; HibernateTransactionObject txObject = (HibernateTransactionObject) transaction;
@ -476,8 +477,8 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
if (!definition.isReadOnly() && !txObject.isNewSession()) { if (!definition.isReadOnly() && !txObject.isNewSession()) {
// We need AUTO or COMMIT for a non-read-only transaction. // We need AUTO or COMMIT for a non-read-only transaction.
FlushMode flushMode = session.getFlushMode(); FlushMode flushMode = SessionFactoryUtils.getFlushMode(session);
if (session.getFlushMode().equals(FlushMode.MANUAL)) { if (FlushMode.MANUAL.equals(flushMode)) {
session.setFlushMode(FlushMode.AUTO); session.setFlushMode(FlushMode.AUTO);
txObject.getSessionHolder().setPreviousFlushMode(flushMode); txObject.getSessionHolder().setPreviousFlushMode(flushMode);
} }
@ -627,6 +628,7 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
} }
@Override @Override
@SuppressWarnings("deprecation")
protected void doCleanupAfterCompletion(Object transaction) { protected void doCleanupAfterCompletion(Object transaction) {
HibernateTransactionObject txObject = (HibernateTransactionObject) transaction; HibernateTransactionObject txObject = (HibernateTransactionObject) transaction;
@ -703,6 +705,7 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
* @param session the Hibernate Session to check * @param session the Hibernate Session to check
* @see ConnectionReleaseMode#ON_CLOSE * @see ConnectionReleaseMode#ON_CLOSE
*/ */
@SuppressWarnings("deprecation")
protected boolean isSameConnectionForEntireSession(Session session) { protected boolean isSameConnectionForEntireSession(Session session) {
if (!(session instanceof SessionImplementor)) { if (!(session instanceof SessionImplementor)) {
// The best we can do is to assume we're safe. // The best we can do is to assume we're safe.

View File

@ -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,10 +16,12 @@
package org.springframework.orm.hibernate5; package org.springframework.orm.hibernate5;
import java.lang.reflect.Method;
import javax.sql.DataSource; import javax.sql.DataSource;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.hibernate.FlushMode;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.JDBCException; import org.hibernate.JDBCException;
import org.hibernate.NonUniqueObjectException; import org.hibernate.NonUniqueObjectException;
@ -59,6 +61,8 @@ import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.dao.InvalidDataAccessResourceUsageException; import org.springframework.dao.InvalidDataAccessResourceUsageException;
import org.springframework.dao.PessimisticLockingFailureException; import org.springframework.dao.PessimisticLockingFailureException;
import org.springframework.jdbc.datasource.DataSourceUtils; import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
/** /**
* Helper class featuring methods for Hibernate Session handling. * Helper class featuring methods for Hibernate Session handling.
@ -86,6 +90,57 @@ public abstract class SessionFactoryUtils {
static final Log logger = LogFactory.getLog(SessionFactoryUtils.class); static final Log logger = LogFactory.getLog(SessionFactoryUtils.class);
private static Method getFlushMode;
static {
try {
// Hibernate 5.2+ getHibernateFlushMode()
getFlushMode = Session.class.getMethod("getHibernateFlushMode");
}
catch (NoSuchMethodException ex) {
try {
// Hibernate 5.0/5.1 getFlushMode() with FlushMode return type
getFlushMode = Session.class.getMethod("getFlushMode");
}
catch (NoSuchMethodException ex2) {
throw new IllegalStateException("No compatible Hibernate getFlushMode signature found", ex2);
}
}
// Check that it is the Hibernate FlushMode type, not JPA's...
Assert.state(FlushMode.class == getFlushMode.getReturnType());
}
/**
* Get the native Hibernate FlushMode, adapting between Hibernate 5.0/5.1 and 5.2+.
* @param session the Hibernate Session to get the flush mode from
* @return the FlushMode (never {@code null})
* @since 4.3
*/
static FlushMode getFlushMode(Session session) {
return (FlushMode) ReflectionUtils.invokeMethod(getFlushMode, session);
}
/**
* Perform actual closing of the Hibernate Session,
* catching and logging any cleanup exceptions thrown.
* @param session the Hibernate Session to close (may be {@code null})
* @see Session#close()
*/
public static void closeSession(Session session) {
if (session != null) {
try {
session.close();
}
catch (HibernateException ex) {
logger.debug("Could not close Hibernate Session", ex);
}
catch (Throwable ex) {
logger.debug("Unexpected exception on closing Hibernate Session", ex);
}
}
}
/** /**
* Determine the DataSource of the given SessionFactory. * Determine the DataSource of the given SessionFactory.
* @param sessionFactory the SessionFactory to check * @param sessionFactory the SessionFactory to check
@ -114,26 +169,6 @@ public abstract class SessionFactoryUtils {
return null; return null;
} }
/**
* Perform actual closing of the Hibernate Session,
* catching and logging any cleanup exceptions thrown.
* @param session the Hibernate Session to close (may be {@code null})
* @see Session#close()
*/
public static void closeSession(Session session) {
if (session != null) {
try {
session.close();
}
catch (HibernateException ex) {
logger.debug("Could not close Hibernate Session", ex);
}
catch (Throwable ex) {
logger.debug("Unexpected exception on closing Hibernate Session", ex);
}
}
}
/** /**
* Convert the given HibernateException to an appropriate exception * Convert the given HibernateException to an appropriate exception
* from the {@code org.springframework.dao} hierarchy. * from the {@code org.springframework.dao} hierarchy.

View File

@ -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.
@ -38,6 +38,7 @@ public class SpringJtaSessionContext extends JTASessionContext {
} }
@Override @Override
@SuppressWarnings("deprecation")
protected Session buildOrObtainSession() { protected Session buildOrObtainSession() {
Session session = super.buildOrObtainSession(); Session session = super.buildOrObtainSession();
if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) { if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {

View File

@ -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.
@ -76,6 +76,7 @@ public class SpringSessionContext implements CurrentSessionContext {
* Retrieve the Spring-managed Session for the current thread, if any. * Retrieve the Spring-managed Session for the current thread, if any.
*/ */
@Override @Override
@SuppressWarnings("deprecation")
public Session currentSession() throws HibernateException { public Session currentSession() throws HibernateException {
Object value = TransactionSynchronizationManager.getResource(this.sessionFactory); Object value = TransactionSynchronizationManager.getResource(this.sessionFactory);
if (value instanceof Session) { if (value instanceof Session) {
@ -91,7 +92,7 @@ public class SpringSessionContext implements CurrentSessionContext {
sessionHolder.setSynchronizedWithTransaction(true); sessionHolder.setSynchronizedWithTransaction(true);
// Switch to FlushMode.AUTO, as we have to assume a thread-bound Session // Switch to FlushMode.AUTO, as we have to assume a thread-bound Session
// with FlushMode.MANUAL, which needs to allow flushing within the transaction. // with FlushMode.MANUAL, which needs to allow flushing within the transaction.
FlushMode flushMode = session.getFlushMode(); FlushMode flushMode = SessionFactoryUtils.getFlushMode(session);
if (flushMode.equals(FlushMode.MANUAL) && if (flushMode.equals(FlushMode.MANUAL) &&
!TransactionSynchronizationManager.isCurrentTransactionReadOnly()) { !TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
session.setFlushMode(FlushMode.AUTO); session.setFlushMode(FlushMode.AUTO);

View File

@ -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.
@ -111,6 +111,7 @@ public class SpringSessionSynchronization implements TransactionSynchronization,
} }
@Override @Override
@SuppressWarnings("deprecation")
public void beforeCompletion() { public void beforeCompletion() {
try { try {
Session session = this.sessionHolder.getSession(); Session session = this.sessionHolder.getSession();

View File

@ -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.
@ -199,6 +199,7 @@ public class OpenSessionInViewFilter extends OncePerRequestFilter {
* @throws DataAccessResourceFailureException if the Session could not be created * @throws DataAccessResourceFailureException if the Session could not be created
* @see FlushMode#MANUAL * @see FlushMode#MANUAL
*/ */
@SuppressWarnings("deprecation")
protected Session openSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException { protected Session openSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException {
try { try {
Session session = sessionFactory.openSession(); Session session = sessionFactory.openSession();

View File

@ -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.
@ -179,6 +179,7 @@ public class OpenSessionInViewInterceptor implements AsyncWebRequestInterceptor
* @throws DataAccessResourceFailureException if the Session could not be created * @throws DataAccessResourceFailureException if the Session could not be created
* @see FlushMode#MANUAL * @see FlushMode#MANUAL
*/ */
@SuppressWarnings("deprecation")
protected Session openSession() throws DataAccessResourceFailureException { protected Session openSession() throws DataAccessResourceFailureException {
try { try {
Session session = getSessionFactory().openSession(); Session session = getSessionFactory().openSession();

View File

@ -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.
@ -102,6 +102,7 @@ public class OpenSessionInterceptor implements MethodInterceptor, InitializingBe
* @throws DataAccessResourceFailureException if the Session could not be created * @throws DataAccessResourceFailureException if the Session could not be created
* @see FlushMode#MANUAL * @see FlushMode#MANUAL
*/ */
@SuppressWarnings("deprecation")
protected Session openSession() throws DataAccessResourceFailureException { protected Session openSession() throws DataAccessResourceFailureException {
try { try {
Session session = getSessionFactory().openSession(); Session session = getSessionFactory().openSession();

View File

@ -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.
@ -66,13 +66,14 @@ import org.springframework.orm.jpa.JpaSystemException;
import org.springframework.transaction.InvalidIsolationLevelException; import org.springframework.transaction.InvalidIsolationLevelException;
import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionException; import org.springframework.transaction.TransactionException;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
/** /**
* {@link org.springframework.orm.jpa.JpaDialect} implementation for * {@link org.springframework.orm.jpa.JpaDialect} implementation for
* Hibernate EntityManager. Developed and tested against Hibernate 3.6, * Hibernate EntityManager. Developed and tested against Hibernate 3.6,
* 4.2/4.3 as well as 5.0. * 4.2/4.3 as well as 5.0/5.1/5.2.
* *
* @author Juergen Hoeller * @author Juergen Hoeller
* @author Costin Leau * @author Costin Leau
@ -88,6 +89,8 @@ public class HibernateJpaDialect extends DefaultJpaDialect {
private static Class<?> pessimisticLockExceptionClass; private static Class<?> pessimisticLockExceptionClass;
private static Method getFlushMode;
static { static {
// Checking for Hibernate 4.x's Optimistic/PessimisticEntityLockException // Checking for Hibernate 4.x's Optimistic/PessimisticEntityLockException
ClassLoader cl = HibernateJpaDialect.class.getClassLoader(); ClassLoader cl = HibernateJpaDialect.class.getClassLoader();
@ -104,6 +107,22 @@ public class HibernateJpaDialect extends DefaultJpaDialect {
catch (ClassNotFoundException ex) { catch (ClassNotFoundException ex) {
pessimisticLockExceptionClass = null; pessimisticLockExceptionClass = null;
} }
try {
// Hibernate 5.2+ getHibernateFlushMode()
getFlushMode = Session.class.getMethod("getHibernateFlushMode");
}
catch (NoSuchMethodException ex) {
try {
// Classic Hibernate getFlushMode() with FlushMode return type
getFlushMode = Session.class.getMethod("getFlushMode");
}
catch (NoSuchMethodException ex2) {
throw new IllegalStateException("No compatible Hibernate getFlushMode signature found", ex2);
}
}
// Check that it is the Hibernate FlushMode type, not JPA's...
Assert.state(FlushMode.class == getFlushMode.getReturnType());
} }
@ -184,7 +203,7 @@ public class HibernateJpaDialect extends DefaultJpaDialect {
} }
protected FlushMode prepareFlushMode(Session session, boolean readOnly) throws PersistenceException { protected FlushMode prepareFlushMode(Session session, boolean readOnly) throws PersistenceException {
FlushMode flushMode = session.getFlushMode(); FlushMode flushMode = (FlushMode) ReflectionUtils.invokeMethod(getFlushMode, session);
if (readOnly) { if (readOnly) {
// We should suppress flushing for a read-only transaction. // We should suppress flushing for a read-only transaction.
if (!flushMode.equals(FlushMode.MANUAL)) { if (!flushMode.equals(FlushMode.MANUAL)) {

View File

@ -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.
@ -35,7 +35,7 @@ import org.hibernate.dialect.SQLServerDialect;
/** /**
* {@link org.springframework.orm.jpa.JpaVendorAdapter} implementation for Hibernate * {@link org.springframework.orm.jpa.JpaVendorAdapter} implementation for Hibernate
* EntityManager. Developed and tested against Hibernate 3.6, 4.2/4.3 as well as 5.0. * EntityManager. Developed and tested against Hibernate 3.6, 4.2/4.3 as well as 5.x.
* <b>Hibernate 4.2+ is strongly recommended for use with Spring 4.0+.</b> * <b>Hibernate 4.2+ is strongly recommended for use with Spring 4.0+.</b>
* *
* <p>Exposes Hibernate's persistence provider and EntityManager extension interface, * <p>Exposes Hibernate's persistence provider and EntityManager extension interface,