diff --git a/build.gradle b/build.gradle index 44bfb6eee1..a24988227d 100644 --- a/build.gradle +++ b/build.gradle @@ -46,7 +46,7 @@ configure(allprojects) { project -> ext.hamcrestVersion = "1.3" ext.hibernate3Version = "3.6.10.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.hibval5Version = "5.2.4.Final" ext.hsqldbVersion = "2.3.4" @@ -798,7 +798,6 @@ project("spring-orm-hibernate5") { provided(project(":spring-tx")) optional(project(":spring-web")) optional("org.hibernate:hibernate-core:${hibernate5Version}") - optional("org.hibernate:hibernate-entitymanager:${hibernate5Version}") optional("javax.servlet:javax.servlet-api:3.0.1") optional("javax.transaction:javax.transaction-api:${jtaVersion}") } diff --git a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/HibernateTransactionManager.java b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/HibernateTransactionManager.java index ad527e3867..c9ac33332c 100644 --- a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/HibernateTransactionManager.java +++ b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/HibernateTransactionManager.java @@ -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"); * 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()) { // We need AUTO or COMMIT for a non-read-only transaction. FlushMode flushMode = session.getFlushMode(); - if (session.getFlushMode().equals(FlushMode.MANUAL)) { + if (FlushMode.MANUAL.equals(flushMode)) { session.setFlushMode(FlushMode.AUTO); txObject.getSessionHolder().setPreviousFlushMode(flushMode); } diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateTemplate.java b/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateTemplate.java index 878357d452..06537de1df 100644 --- a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateTemplate.java +++ b/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateTemplate.java @@ -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. @@ -27,7 +27,6 @@ import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - import org.hibernate.Criteria; import org.hibernate.Filter; import org.hibernate.FlushMode; @@ -35,7 +34,6 @@ import org.hibernate.Hibernate; import org.hibernate.HibernateException; import org.hibernate.LockMode; import org.hibernate.LockOptions; -import org.hibernate.Query; import org.hibernate.ReplicationMode; import org.hibernate.Session; import org.hibernate.SessionFactory; @@ -211,7 +209,7 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean *

To specify the query region to be used for queries cached * by this template, set the "queryCacheRegion" property. * @see #setQueryCacheRegion - * @see Query#setCacheable + * @see org.hibernate.Query#setCacheable * @see Criteria#setCacheable */ public void setCacheQueries(boolean cacheQueries) { @@ -232,7 +230,7 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean *

The cache region will not take effect unless queries created by this * template are configured to be cached via the "cacheQueries" property. * @see #setCacheQueries - * @see Query#setCacheRegion + * @see org.hibernate.Query#setCacheRegion * @see Criteria#setCacheRegion */ 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} * @throws DataAccessException in case of Hibernate errors */ + @SuppressWarnings("deprecation") protected T doExecute(HibernateCallback action, boolean enforceNativeSession) throws DataAccessException { Assert.notNull(action, "Callback object must not be null"); @@ -499,7 +498,7 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean public List loadAll(final Class entityClass) throws DataAccessException { return executeWithNativeSession(new HibernateCallback>() { @Override - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "deprecation"}) public List doInHibernate(Session session) throws HibernateException { Criteria criteria = session.createCriteria(entityClass); 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 { return executeWithNativeSession(new HibernateCallback>() { @Override + @SuppressWarnings({"rawtypes", "deprecation"}) public List doInHibernate(Session session) throws HibernateException { - Query queryObject = session.createQuery(queryString); + org.hibernate.Query queryObject = session.createQuery(queryString); prepareQuery(queryObject); if (values != null) { for (int i = 0; i < values.length; i++) { @@ -891,13 +891,12 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean } return executeWithNativeSession(new HibernateCallback>() { @Override + @SuppressWarnings({"rawtypes", "deprecation"}) public List doInHibernate(Session session) throws HibernateException { - Query queryObject = session.createQuery(queryString); + org.hibernate.Query queryObject = session.createQuery(queryString); prepareQuery(queryObject); - if (values != null) { - for (int i = 0; i < values.length; i++) { - applyNamedParameterToQuery(queryObject, paramNames[i], values[i]); - } + for (int i = 0; i < values.length; i++) { + applyNamedParameterToQuery(queryObject, paramNames[i], values[i]); } return queryObject.list(); } @@ -910,8 +909,9 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean return executeWithNativeSession(new HibernateCallback>() { @Override + @SuppressWarnings({"rawtypes", "deprecation"}) public List doInHibernate(Session session) throws HibernateException { - Query queryObject = session.createQuery(queryString); + org.hibernate.Query queryObject = session.createQuery(queryString); prepareQuery(queryObject); queryObject.setProperties(valueBean); return queryObject.list(); @@ -928,8 +928,9 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean public List findByNamedQuery(final String queryName, final Object... values) throws DataAccessException { return executeWithNativeSession(new HibernateCallback>() { @Override + @SuppressWarnings({"rawtypes", "deprecation"}) public List doInHibernate(Session session) throws HibernateException { - Query queryObject = session.getNamedQuery(queryName); + org.hibernate.Query queryObject = session.getNamedQuery(queryName); prepareQuery(queryObject); if (values != null) { for (int i = 0; i < values.length; i++) { @@ -958,8 +959,9 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean } return executeWithNativeSession(new HibernateCallback>() { @Override + @SuppressWarnings({"rawtypes", "deprecation"}) public List doInHibernate(Session session) throws HibernateException { - Query queryObject = session.getNamedQuery(queryName); + org.hibernate.Query queryObject = session.getNamedQuery(queryName); prepareQuery(queryObject); if (values != null) { for (int i = 0; i < values.length; i++) { @@ -977,8 +979,9 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean return executeWithNativeSession(new HibernateCallback>() { @Override + @SuppressWarnings({"rawtypes", "deprecation"}) public List doInHibernate(Session session) throws HibernateException { - Query queryObject = session.getNamedQuery(queryName); + org.hibernate.Query queryObject = session.getNamedQuery(queryName); prepareQuery(queryObject); queryObject.setProperties(valueBean); return queryObject.list(); @@ -1033,6 +1036,7 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean } @Override + @SuppressWarnings("deprecation") public List findByExample( final String entityName, final T exampleEntity, final int firstResult, final int maxResults) throws DataAccessException { @@ -1066,8 +1070,9 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean public Iterator iterate(final String queryString, final Object... values) throws DataAccessException { return executeWithNativeSession(new HibernateCallback>() { @Override + @SuppressWarnings({"rawtypes", "deprecation"}) public Iterator doInHibernate(Session session) throws HibernateException { - Query queryObject = session.createQuery(queryString); + org.hibernate.Query queryObject = session.createQuery(queryString); prepareQuery(queryObject); if (values != null) { 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 { return executeWithNativeSession(new HibernateCallback() { @Override + @SuppressWarnings({"rawtypes", "deprecation"}) public Integer doInHibernate(Session session) throws HibernateException { - Query queryObject = session.createQuery(queryString); + org.hibernate.Query queryObject = session.createQuery(queryString); prepareQuery(queryObject); if (values != null) { for (int i = 0; i < values.length; i++) { @@ -1122,7 +1128,7 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean * @see FlushMode#MANUAL */ 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( "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."); @@ -1136,7 +1142,8 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean * @see #setCacheQueries * @see #setQueryCacheRegion */ - protected void prepareQuery(Query queryObject) { + @SuppressWarnings({"rawtypes", "deprecation"}) + protected void prepareQuery(org.hibernate.Query queryObject) { if (isCacheQueries()) { queryObject.setCacheable(true); if (getQueryCacheRegion() != null) { @@ -1192,7 +1199,8 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean * @param value the value of the parameter * @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 { if (value instanceof Collection) { @@ -1221,6 +1229,7 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean } @Override + @SuppressWarnings("deprecation") public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 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. // Applies to createQuery, getNamedQuery, createCriteria. - if (retVal instanceof Query) { - prepareQuery(((Query) retVal)); + if (retVal instanceof org.hibernate.Query) { + prepareQuery(((org.hibernate.Query) retVal)); } if (retVal instanceof Criteria) { prepareCriteria(((Criteria) retVal)); diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateTransactionManager.java b/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateTransactionManager.java index d26f18b805..93c815bb46 100644 --- a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateTransactionManager.java +++ b/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/HibernateTransactionManager.java @@ -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. @@ -412,6 +412,7 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana } @Override + @SuppressWarnings("deprecation") protected void doBegin(Object transaction, TransactionDefinition definition) { HibernateTransactionObject txObject = (HibernateTransactionObject) transaction; @@ -476,8 +477,8 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana if (!definition.isReadOnly() && !txObject.isNewSession()) { // We need AUTO or COMMIT for a non-read-only transaction. - FlushMode flushMode = session.getFlushMode(); - if (session.getFlushMode().equals(FlushMode.MANUAL)) { + FlushMode flushMode = SessionFactoryUtils.getFlushMode(session); + if (FlushMode.MANUAL.equals(flushMode)) { session.setFlushMode(FlushMode.AUTO); txObject.getSessionHolder().setPreviousFlushMode(flushMode); } @@ -627,6 +628,7 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana } @Override + @SuppressWarnings("deprecation") protected void doCleanupAfterCompletion(Object transaction) { HibernateTransactionObject txObject = (HibernateTransactionObject) transaction; @@ -703,6 +705,7 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana * @param session the Hibernate Session to check * @see ConnectionReleaseMode#ON_CLOSE */ + @SuppressWarnings("deprecation") protected boolean isSameConnectionForEntireSession(Session session) { if (!(session instanceof SessionImplementor)) { // The best we can do is to assume we're safe. diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SessionFactoryUtils.java b/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SessionFactoryUtils.java index 19151579b8..19867b3cc3 100644 --- a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SessionFactoryUtils.java +++ b/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SessionFactoryUtils.java @@ -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,10 +16,12 @@ package org.springframework.orm.hibernate5; +import java.lang.reflect.Method; import javax.sql.DataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.hibernate.FlushMode; import org.hibernate.HibernateException; import org.hibernate.JDBCException; import org.hibernate.NonUniqueObjectException; @@ -59,6 +61,8 @@ import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.dao.InvalidDataAccessResourceUsageException; import org.springframework.dao.PessimisticLockingFailureException; import org.springframework.jdbc.datasource.DataSourceUtils; +import org.springframework.util.Assert; +import org.springframework.util.ReflectionUtils; /** * Helper class featuring methods for Hibernate Session handling. @@ -86,6 +90,57 @@ public abstract class SessionFactoryUtils { 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. * @param sessionFactory the SessionFactory to check @@ -114,26 +169,6 @@ public abstract class SessionFactoryUtils { 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 * from the {@code org.springframework.dao} hierarchy. diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SpringJtaSessionContext.java b/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SpringJtaSessionContext.java index a4eb34ed40..eed37f1971 100644 --- a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SpringJtaSessionContext.java +++ b/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SpringJtaSessionContext.java @@ -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. @@ -38,6 +38,7 @@ public class SpringJtaSessionContext extends JTASessionContext { } @Override + @SuppressWarnings("deprecation") protected Session buildOrObtainSession() { Session session = super.buildOrObtainSession(); if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) { diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SpringSessionContext.java b/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SpringSessionContext.java index 2ad96a7901..250fd60921 100644 --- a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SpringSessionContext.java +++ b/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SpringSessionContext.java @@ -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. @@ -76,6 +76,7 @@ public class SpringSessionContext implements CurrentSessionContext { * Retrieve the Spring-managed Session for the current thread, if any. */ @Override + @SuppressWarnings("deprecation") public Session currentSession() throws HibernateException { Object value = TransactionSynchronizationManager.getResource(this.sessionFactory); if (value instanceof Session) { @@ -91,7 +92,7 @@ public class SpringSessionContext implements CurrentSessionContext { sessionHolder.setSynchronizedWithTransaction(true); // Switch to FlushMode.AUTO, as we have to assume a thread-bound Session // 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) && !TransactionSynchronizationManager.isCurrentTransactionReadOnly()) { session.setFlushMode(FlushMode.AUTO); diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SpringSessionSynchronization.java b/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SpringSessionSynchronization.java index ca56b71a39..82cf4f4e5f 100644 --- a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SpringSessionSynchronization.java +++ b/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/SpringSessionSynchronization.java @@ -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. @@ -111,6 +111,7 @@ public class SpringSessionSynchronization implements TransactionSynchronization, } @Override + @SuppressWarnings("deprecation") public void beforeCompletion() { try { Session session = this.sessionHolder.getSession(); diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInViewFilter.java b/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInViewFilter.java index 9324ea4a74..6f067d9c3d 100644 --- a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInViewFilter.java +++ b/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInViewFilter.java @@ -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. @@ -199,6 +199,7 @@ public class OpenSessionInViewFilter extends OncePerRequestFilter { * @throws DataAccessResourceFailureException if the Session could not be created * @see FlushMode#MANUAL */ + @SuppressWarnings("deprecation") protected Session openSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException { try { Session session = sessionFactory.openSession(); diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInViewInterceptor.java b/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInViewInterceptor.java index 40b93f9c0e..5b2ff0bfb5 100644 --- a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInViewInterceptor.java +++ b/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInViewInterceptor.java @@ -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. @@ -179,6 +179,7 @@ public class OpenSessionInViewInterceptor implements AsyncWebRequestInterceptor * @throws DataAccessResourceFailureException if the Session could not be created * @see FlushMode#MANUAL */ + @SuppressWarnings("deprecation") protected Session openSession() throws DataAccessResourceFailureException { try { Session session = getSessionFactory().openSession(); diff --git a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInterceptor.java b/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInterceptor.java index dd1c7c16b5..1fbc396969 100644 --- a/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInterceptor.java +++ b/spring-orm-hibernate5/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInterceptor.java @@ -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. @@ -102,6 +102,7 @@ public class OpenSessionInterceptor implements MethodInterceptor, InitializingBe * @throws DataAccessResourceFailureException if the Session could not be created * @see FlushMode#MANUAL */ + @SuppressWarnings("deprecation") protected Session openSession() throws DataAccessResourceFailureException { try { Session session = getSessionFactory().openSession(); diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaDialect.java b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaDialect.java index 6ff396ea29..3082ffa506 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaDialect.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaDialect.java @@ -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. @@ -66,13 +66,14 @@ import org.springframework.orm.jpa.JpaSystemException; import org.springframework.transaction.InvalidIsolationLevelException; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionException; +import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.ReflectionUtils; /** * {@link org.springframework.orm.jpa.JpaDialect} implementation for * 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 Costin Leau @@ -88,6 +89,8 @@ public class HibernateJpaDialect extends DefaultJpaDialect { private static Class pessimisticLockExceptionClass; + private static Method getFlushMode; + static { // Checking for Hibernate 4.x's Optimistic/PessimisticEntityLockException ClassLoader cl = HibernateJpaDialect.class.getClassLoader(); @@ -104,6 +107,22 @@ public class HibernateJpaDialect extends DefaultJpaDialect { catch (ClassNotFoundException ex) { 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 { - FlushMode flushMode = session.getFlushMode(); + FlushMode flushMode = (FlushMode) ReflectionUtils.invokeMethod(getFlushMode, session); if (readOnly) { // We should suppress flushing for a read-only transaction. if (!flushMode.equals(FlushMode.MANUAL)) { diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaVendorAdapter.java b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaVendorAdapter.java index ccb1510f1e..108eea1319 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaVendorAdapter.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaVendorAdapter.java @@ -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. @@ -35,7 +35,7 @@ import org.hibernate.dialect.SQLServerDialect; /** * {@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. * Hibernate 4.2+ is strongly recommended for use with Spring 4.0+. * *

Exposes Hibernate's persistence provider and EntityManager extension interface,