Consistent use of @Nullable across the codebase (even for internals)

Beyond just formally declaring the current behavior, this revision actually enforces non-null behavior in selected signatures now, not tolerating null values anymore when not explicitly documented. It also changes some utility methods with historic null-in/null-out tolerance towards enforced non-null return values, making them a proper citizen in non-null assignments.

Some issues are left as to-do: in particular a thorough revision of spring-test, and a few tests with unclear failures (ignored as "TODO: NULLABLE") to be sorted out in a follow-up commit.

Issue: SPR-15540
This commit is contained in:
Juergen Hoeller
2017-06-07 14:17:48 +02:00
parent ffc3f6d87d
commit f813712f5b
1493 changed files with 10670 additions and 9172 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2017 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.
@@ -17,6 +17,7 @@
package org.springframework.orm;
import org.springframework.dao.OptimisticLockingFailureException;
import org.springframework.lang.Nullable;
/**
* Exception thrown on an optimistic locking violation for a mapped object.
@@ -61,7 +62,7 @@ public class ObjectOptimisticLockingFailureException extends OptimisticLockingFa
* @param cause the source exception
*/
public ObjectOptimisticLockingFailureException(
Class<?> persistentClass, Object identifier, Throwable cause) {
Class<?> persistentClass, Object identifier, @Nullable Throwable cause) {
this(persistentClass, identifier,
"Object of class [" + persistentClass.getName() + "] with identifier [" + identifier +
@@ -77,7 +78,7 @@ public class ObjectOptimisticLockingFailureException extends OptimisticLockingFa
* @param cause the source exception
*/
public ObjectOptimisticLockingFailureException(
Class<?> persistentClass, Object identifier, String msg, Throwable cause) {
Class<?> persistentClass, Object identifier, String msg, @Nullable Throwable cause) {
super(msg, cause);
this.persistentClass = persistentClass;
@@ -102,7 +103,7 @@ public class ObjectOptimisticLockingFailureException extends OptimisticLockingFa
* @param cause the source exception
*/
public ObjectOptimisticLockingFailureException(
String persistentClassName, Object identifier, Throwable cause) {
String persistentClassName, Object identifier, @Nullable Throwable cause) {
this(persistentClassName, identifier,
"Object of class [" + persistentClassName + "] with identifier [" + identifier +
@@ -118,7 +119,7 @@ public class ObjectOptimisticLockingFailureException extends OptimisticLockingFa
* @param cause the source exception
*/
public ObjectOptimisticLockingFailureException(
String persistentClassName, Object identifier, String msg, Throwable cause) {
String persistentClassName, Object identifier, String msg, @Nullable Throwable cause) {
super(msg, cause);
this.persistentClass = persistentClassName;
@@ -130,6 +131,7 @@ public class ObjectOptimisticLockingFailureException extends OptimisticLockingFa
* Return the persistent class of the object for which the locking failed.
* If no Class was specified, this method returns null.
*/
@Nullable
public Class<?> getPersistentClass() {
return (this.persistentClass instanceof Class ? (Class<?>) this.persistentClass : null);
}
@@ -138,6 +140,7 @@ public class ObjectOptimisticLockingFailureException extends OptimisticLockingFa
* Return the name of the persistent class of the object for which the locking failed.
* Will work for both Class objects and String names.
*/
@Nullable
public String getPersistentClassName() {
if (this.persistentClass instanceof Class) {
return ((Class<?>) this.persistentClass).getName();
@@ -149,7 +152,7 @@ public class ObjectOptimisticLockingFailureException extends OptimisticLockingFa
* Return the identifier of the object for which the locking failed.
*/
public Object getIdentifier() {
return identifier;
return this.identifier;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2017 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.
@@ -17,6 +17,7 @@
package org.springframework.orm;
import org.springframework.dao.DataRetrievalFailureException;
import org.springframework.lang.Nullable;
/**
* Exception thrown if a mapped object could not be retrieved via its identifier.
@@ -64,7 +65,7 @@ public class ObjectRetrievalFailureException extends DataRetrievalFailureExcepti
* @param cause the source exception
*/
public ObjectRetrievalFailureException(
Class<?> persistentClass, Object identifier, String msg, Throwable cause) {
Class<?> persistentClass, Object identifier, String msg, @Nullable Throwable cause) {
super(msg, cause);
this.persistentClass = persistentClass;
@@ -92,7 +93,7 @@ public class ObjectRetrievalFailureException extends DataRetrievalFailureExcepti
* @param cause the source exception
*/
public ObjectRetrievalFailureException(
String persistentClassName, Object identifier, String msg, Throwable cause) {
String persistentClassName, Object identifier, String msg, @Nullable Throwable cause) {
super(msg, cause);
this.persistentClass = persistentClassName;
@@ -104,6 +105,7 @@ public class ObjectRetrievalFailureException extends DataRetrievalFailureExcepti
* Return the persistent class of the object that was not found.
* If no Class was specified, this method returns null.
*/
@Nullable
public Class<?> getPersistentClass() {
return (this.persistentClass instanceof Class ? (Class<?>) this.persistentClass : null);
}
@@ -112,6 +114,7 @@ public class ObjectRetrievalFailureException extends DataRetrievalFailureExcepti
* Return the name of the persistent class of the object that was not found.
* Will work for both Class objects and String names.
*/
@Nullable
public String getPersistentClassName() {
if (this.persistentClass instanceof Class) {
return ((Class<?>) this.persistentClass).getName();
@@ -123,7 +126,7 @@ public class ObjectRetrievalFailureException extends DataRetrievalFailureExcepti
* Return the identifier of the object that was not found.
*/
public Object getIdentifier() {
return identifier;
return this.identifier;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2017 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.
@@ -19,6 +19,7 @@ package org.springframework.orm.hibernate5;
import org.hibernate.HibernateException;
import org.springframework.dao.UncategorizedDataAccessException;
import org.springframework.lang.Nullable;
/**
* Hibernate-specific subclass of UncategorizedDataAccessException,
@@ -37,7 +38,7 @@ public class HibernateSystemException extends UncategorizedDataAccessException {
* wrapping an arbitrary HibernateException.
* @param cause the HibernateException thrown
*/
public HibernateSystemException(HibernateException cause) {
public HibernateSystemException(@Nullable HibernateException cause) {
super(cause != null ? cause.getMessage() : null, cause);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.
@@ -24,7 +24,6 @@ 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;
@@ -151,10 +150,23 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
* Return the Hibernate SessionFactory that should be used to create
* Hibernate Sessions.
*/
@Nullable
public SessionFactory getSessionFactory() {
return this.sessionFactory;
}
/**
* Obtain the SessionFactory for actual use.
* @return the SessionFactory (never {@code null})
* @throws IllegalStateException in case of no SessionFactory set
* @since 5.0
*/
protected final SessionFactory obtainSessionFactory() {
SessionFactory sessionFactory = getSessionFactory();
Assert.state(sessionFactory != null, "No SessionFactory set");
return sessionFactory;
}
/**
* Set one or more names of Hibernate filters to be activated for all
* Sessions that this accessor works with.
@@ -262,6 +274,7 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
/**
* Return the name of the cache region for queries executed by this template.
*/
@Nullable
public String getQueryCacheRegion() {
return this.queryCacheRegion;
}
@@ -346,13 +359,13 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
Session session = null;
boolean isNew = false;
try {
session = getSessionFactory().getCurrentSession();
session = obtainSessionFactory().getCurrentSession();
}
catch (HibernateException ex) {
logger.debug("Could not retrieve pre-bound Hibernate session", ex);
}
if (session == null) {
session = getSessionFactory().openSession();
session = obtainSessionFactory().openSession();
session.setFlushMode(FlushMode.MANUAL);
isNew = true;
}
@@ -445,15 +458,12 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
public <T> T get(final Class<T> entityClass, final Serializable id, @Nullable final LockMode lockMode)
throws DataAccessException {
return executeWithNativeSession(new HibernateCallback<T>() {
@Override
public T doInHibernate(Session session) throws HibernateException {
if (lockMode != null) {
return session.get(entityClass, id, new LockOptions(lockMode));
}
else {
return session.get(entityClass, id);
}
return executeWithNativeSession(session -> {
if (lockMode != null) {
return session.get(entityClass, id, new LockOptions(lockMode));
}
else {
return session.get(entityClass, id);
}
});
}
@@ -467,15 +477,12 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
public Object get(final String entityName, final Serializable id, @Nullable final LockMode lockMode)
throws DataAccessException {
return executeWithNativeSession(new HibernateCallback<Object>() {
@Override
public Object doInHibernate(Session session) throws HibernateException {
if (lockMode != null) {
return session.get(entityName, id, new LockOptions(lockMode));
}
else {
return session.get(entityName, id);
}
return executeWithNativeSession(session -> {
if (lockMode != null) {
return session.get(entityName, id, new LockOptions(lockMode));
}
else {
return session.get(entityName, id);
}
});
}
@@ -489,17 +496,14 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
public <T> T load(final Class<T> entityClass, final Serializable id, @Nullable final LockMode lockMode)
throws DataAccessException {
return executeWithNativeSession(new HibernateCallback<T>() {
@Override
public T doInHibernate(Session session) throws HibernateException {
if (lockMode != null) {
return session.load(entityClass, id, new LockOptions(lockMode));
}
else {
return session.load(entityClass, id);
}
return nonNull(executeWithNativeSession(session -> {
if (lockMode != null) {
return session.load(entityClass, id, new LockOptions(lockMode));
}
});
else {
return session.load(entityClass, id);
}
}));
}
@Override
@@ -511,41 +515,33 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
public Object load(final String entityName, final Serializable id, @Nullable final LockMode lockMode)
throws DataAccessException {
return executeWithNativeSession(new HibernateCallback<Object>() {
@Override
public Object doInHibernate(Session session) throws HibernateException {
if (lockMode != null) {
return session.load(entityName, id, new LockOptions(lockMode));
}
else {
return session.load(entityName, id);
}
return nonNull(executeWithNativeSession(session -> {
if (lockMode != null) {
return session.load(entityName, id, new LockOptions(lockMode));
}
});
else {
return session.load(entityName, id);
}
}));
}
@Override
@SuppressWarnings({"unchecked", "deprecation"})
public <T> List<T> loadAll(final Class<T> entityClass) throws DataAccessException {
return executeWithNativeSession(new HibernateCallback<List<T>>() {
@Override
@SuppressWarnings({"unchecked", "deprecation"})
public List<T> doInHibernate(Session session) throws HibernateException {
Criteria criteria = session.createCriteria(entityClass);
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
prepareCriteria(criteria);
return criteria.list();
}
});
return nonNull(executeWithNativeSession((HibernateCallback<List<T>>) session -> {
Criteria criteria = session.createCriteria(entityClass);
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
prepareCriteria(criteria);
return criteria.list();
}));
}
@Override
@SuppressWarnings({"deprecation"})
public void load(final Object entity, final Serializable id) throws DataAccessException {
executeWithNativeSession(new HibernateCallback<Object>() {
@Override
public Object doInHibernate(Session session) throws HibernateException {
session.load(entity, id);
return null;
}
executeWithNativeSession(session -> {
session.load(entity, id);
return null;
});
}
@@ -556,38 +552,29 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
@Override
public void refresh(final Object entity, @Nullable final LockMode lockMode) throws DataAccessException {
executeWithNativeSession(new HibernateCallback<Object>() {
@Override
public Object doInHibernate(Session session) throws HibernateException {
if (lockMode != null) {
session.refresh(entity, new LockOptions(lockMode));
}
else {
session.refresh(entity);
}
return null;
executeWithNativeSession(session -> {
if (lockMode != null) {
session.refresh(entity, new LockOptions(lockMode));
}
else {
session.refresh(entity);
}
return null;
});
}
@Override
public boolean contains(final Object entity) throws DataAccessException {
return executeWithNativeSession(new HibernateCallback<Boolean>() {
@Override
public Boolean doInHibernate(Session session) {
return session.contains(entity);
}
});
Boolean result = executeWithNativeSession(session -> session.contains(entity));
Assert.state(result != null, "No contains result");
return result;
}
@Override
public void evict(final Object entity) throws DataAccessException {
executeWithNativeSession(new HibernateCallback<Object>() {
@Override
public Object doInHibernate(Session session) throws HibernateException {
session.evict(entity);
return null;
}
executeWithNativeSession(session -> {
session.evict(entity);
return null;
});
}
@@ -603,7 +590,7 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
@Override
public Filter enableFilter(String filterName) throws IllegalStateException {
Session session = getSessionFactory().getCurrentSession();
Session session = obtainSessionFactory().getCurrentSession();
Filter filter = session.getEnabledFilter(filterName);
if (filter == null) {
filter = session.enableFilter(filterName);
@@ -618,12 +605,9 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
@Override
public void lock(final Object entity, final LockMode lockMode) throws DataAccessException {
executeWithNativeSession(new HibernateCallback<Object>() {
@Override
public Object doInHibernate(Session session) throws HibernateException {
session.buildLockRequest(new LockOptions(lockMode)).lock(entity);
return null;
}
executeWithNativeSession(session -> {
session.buildLockRequest(new LockOptions(lockMode)).lock(entity);
return null;
});
}
@@ -631,35 +615,26 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
public void lock(final String entityName, final Object entity, final LockMode lockMode)
throws DataAccessException {
executeWithNativeSession(new HibernateCallback<Object>() {
@Override
public Object doInHibernate(Session session) throws HibernateException {
session.buildLockRequest(new LockOptions(lockMode)).lock(entityName, entity);
return null;
}
executeWithNativeSession(session -> {
session.buildLockRequest(new LockOptions(lockMode)).lock(entityName, entity);
return null;
});
}
@Override
public Serializable save(final Object entity) throws DataAccessException {
return executeWithNativeSession(new HibernateCallback<Serializable>() {
@Override
public Serializable doInHibernate(Session session) throws HibernateException {
checkWriteOperationAllowed(session);
return session.save(entity);
}
});
return nonNull(executeWithNativeSession(session -> {
checkWriteOperationAllowed(session);
return session.save(entity);
}));
}
@Override
public Serializable save(final String entityName, final Object entity) throws DataAccessException {
return executeWithNativeSession(new HibernateCallback<Serializable>() {
@Override
public Serializable doInHibernate(Session session) throws HibernateException {
checkWriteOperationAllowed(session);
return session.save(entityName, entity);
}
});
return nonNull(executeWithNativeSession(session -> {
checkWriteOperationAllowed(session);
return session.save(entityName, entity);
}));
}
@Override
@@ -669,16 +644,13 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
@Override
public void update(final Object entity, @Nullable final LockMode lockMode) throws DataAccessException {
executeWithNativeSession(new HibernateCallback<Object>() {
@Override
public Object doInHibernate(Session session) throws HibernateException {
checkWriteOperationAllowed(session);
session.update(entity);
if (lockMode != null) {
session.buildLockRequest(new LockOptions(lockMode)).lock(entity);
}
return null;
executeWithNativeSession(session -> {
checkWriteOperationAllowed(session);
session.update(entity);
if (lockMode != null) {
session.buildLockRequest(new LockOptions(lockMode)).lock(entity);
}
return null;
});
}
@@ -691,40 +663,31 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
public void update(final String entityName, final Object entity, @Nullable final LockMode lockMode)
throws DataAccessException {
executeWithNativeSession(new HibernateCallback<Object>() {
@Override
public Object doInHibernate(Session session) throws HibernateException {
checkWriteOperationAllowed(session);
session.update(entityName, entity);
if (lockMode != null) {
session.buildLockRequest(new LockOptions(lockMode)).lock(entityName, entity);
}
return null;
executeWithNativeSession(session -> {
checkWriteOperationAllowed(session);
session.update(entityName, entity);
if (lockMode != null) {
session.buildLockRequest(new LockOptions(lockMode)).lock(entityName, entity);
}
return null;
});
}
@Override
public void saveOrUpdate(final Object entity) throws DataAccessException {
executeWithNativeSession(new HibernateCallback<Object>() {
@Override
public Object doInHibernate(Session session) throws HibernateException {
checkWriteOperationAllowed(session);
session.saveOrUpdate(entity);
return null;
}
executeWithNativeSession(session -> {
checkWriteOperationAllowed(session);
session.saveOrUpdate(entity);
return null;
});
}
@Override
public void saveOrUpdate(final String entityName, final Object entity) throws DataAccessException {
executeWithNativeSession(new HibernateCallback<Object>() {
@Override
public Object doInHibernate(Session session) throws HibernateException {
checkWriteOperationAllowed(session);
session.saveOrUpdate(entityName, entity);
return null;
}
executeWithNativeSession(session -> {
checkWriteOperationAllowed(session);
session.saveOrUpdate(entityName, entity);
return null;
});
}
@@ -732,13 +695,10 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
public void replicate(final Object entity, final ReplicationMode replicationMode)
throws DataAccessException {
executeWithNativeSession(new HibernateCallback<Object>() {
@Override
public Object doInHibernate(Session session) throws HibernateException {
checkWriteOperationAllowed(session);
session.replicate(entity, replicationMode);
return null;
}
executeWithNativeSession(session -> {
checkWriteOperationAllowed(session);
session.replicate(entity, replicationMode);
return null;
});
}
@@ -746,62 +706,47 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
public void replicate(final String entityName, final Object entity, final ReplicationMode replicationMode)
throws DataAccessException {
executeWithNativeSession(new HibernateCallback<Object>() {
@Override
public Object doInHibernate(Session session) throws HibernateException {
checkWriteOperationAllowed(session);
session.replicate(entityName, entity, replicationMode);
return null;
}
executeWithNativeSession(session -> {
checkWriteOperationAllowed(session);
session.replicate(entityName, entity, replicationMode);
return null;
});
}
@Override
public void persist(final Object entity) throws DataAccessException {
executeWithNativeSession(new HibernateCallback<Object>() {
@Override
public Object doInHibernate(Session session) throws HibernateException {
checkWriteOperationAllowed(session);
session.persist(entity);
return null;
}
executeWithNativeSession(session -> {
checkWriteOperationAllowed(session);
session.persist(entity);
return null;
});
}
@Override
public void persist(final String entityName, final Object entity) throws DataAccessException {
executeWithNativeSession(new HibernateCallback<Object>() {
@Override
public Object doInHibernate(Session session) throws HibernateException {
checkWriteOperationAllowed(session);
session.persist(entityName, entity);
return null;
}
executeWithNativeSession(session -> {
checkWriteOperationAllowed(session);
session.persist(entityName, entity);
return null;
});
}
@Override
@SuppressWarnings("unchecked")
public <T> T merge(final T entity) throws DataAccessException {
return executeWithNativeSession(new HibernateCallback<T>() {
@Override
@SuppressWarnings("unchecked")
public T doInHibernate(Session session) throws HibernateException {
checkWriteOperationAllowed(session);
return (T) session.merge(entity);
}
});
return nonNull(executeWithNativeSession(session -> {
checkWriteOperationAllowed(session);
return (T) session.merge(entity);
}));
}
@Override
@SuppressWarnings("unchecked")
public <T> T merge(final String entityName, final T entity) throws DataAccessException {
return executeWithNativeSession(new HibernateCallback<T>() {
@Override
@SuppressWarnings("unchecked")
public T doInHibernate(Session session) throws HibernateException {
checkWriteOperationAllowed(session);
return (T) session.merge(entityName, entity);
}
});
return nonNull(executeWithNativeSession(session -> {
checkWriteOperationAllowed(session);
return (T) session.merge(entityName, entity);
}));
}
@Override
@@ -811,16 +756,13 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
@Override
public void delete(final Object entity, @Nullable final LockMode lockMode) throws DataAccessException {
executeWithNativeSession(new HibernateCallback<Object>() {
@Override
public Object doInHibernate(Session session) throws HibernateException {
checkWriteOperationAllowed(session);
if (lockMode != null) {
session.buildLockRequest(new LockOptions(lockMode)).lock(entity);
}
session.delete(entity);
return null;
executeWithNativeSession(session -> {
checkWriteOperationAllowed(session);
if (lockMode != null) {
session.buildLockRequest(new LockOptions(lockMode)).lock(entity);
}
session.delete(entity);
return null;
});
}
@@ -833,52 +775,40 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
public void delete(final String entityName, final Object entity, @Nullable final LockMode lockMode)
throws DataAccessException {
executeWithNativeSession(new HibernateCallback<Object>() {
@Override
public Object doInHibernate(Session session) throws HibernateException {
checkWriteOperationAllowed(session);
if (lockMode != null) {
session.buildLockRequest(new LockOptions(lockMode)).lock(entityName, entity);
}
session.delete(entityName, entity);
return null;
executeWithNativeSession(session -> {
checkWriteOperationAllowed(session);
if (lockMode != null) {
session.buildLockRequest(new LockOptions(lockMode)).lock(entityName, entity);
}
session.delete(entityName, entity);
return null;
});
}
@Override
public void deleteAll(final Collection<?> entities) throws DataAccessException {
executeWithNativeSession(new HibernateCallback<Object>() {
@Override
public Object doInHibernate(Session session) throws HibernateException {
checkWriteOperationAllowed(session);
for (Object entity : entities) {
session.delete(entity);
}
return null;
executeWithNativeSession(session -> {
checkWriteOperationAllowed(session);
for (Object entity : entities) {
session.delete(entity);
}
return null;
});
}
@Override
public void flush() throws DataAccessException {
executeWithNativeSession(new HibernateCallback<Object>() {
@Override
public Object doInHibernate(Session session) throws HibernateException {
session.flush();
return null;
}
executeWithNativeSession(session -> {
session.flush();
return null;
});
}
@Override
public void clear() throws DataAccessException {
executeWithNativeSession(new HibernateCallback<Object>() {
@Override
public Object doInHibernate(Session session) {
session.clear();
return null;
}
executeWithNativeSession(session -> {
session.clear();
return null;
});
}
@@ -888,22 +818,19 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
//-------------------------------------------------------------------------
@Override
public List<?> find(final String queryString, final Object... values) throws DataAccessException {
return executeWithNativeSession(new HibernateCallback<List<?>>() {
@Override
@SuppressWarnings({"rawtypes", "deprecation"})
public List<?> doInHibernate(Session session) throws HibernateException {
org.hibernate.Query queryObject = (org.hibernate.Query)
ReflectionUtils.invokeMethod(createQueryMethod, session, queryString);
prepareQuery(queryObject);
if (values != null) {
for (int i = 0; i < values.length; i++) {
queryObject.setParameter(i, values[i]);
}
@SuppressWarnings({"rawtypes", "unchecked", "deprecation"})
public List<?> find(final String queryString, @Nullable final Object... values) throws DataAccessException {
return nonNull(executeWithNativeSession((HibernateCallback<List<?>>) session -> {
org.hibernate.Query queryObject = queryObject(
ReflectionUtils.invokeMethod(createQueryMethod, session, queryString));
prepareQuery(queryObject);
if (values != null) {
for (int i = 0; i < values.length; i++) {
queryObject.setParameter(i, values[i]);
}
return queryObject.list();
}
});
return queryObject.list();
}));
}
@Override
@@ -914,42 +841,36 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
}
@Override
@SuppressWarnings({"rawtypes", "unchecked", "deprecation"})
public List<?> findByNamedParam(final String queryString, final String[] paramNames, final Object[] values)
throws DataAccessException {
if (paramNames.length != values.length) {
throw new IllegalArgumentException("Length of paramNames array must match length of values array");
}
return executeWithNativeSession(new HibernateCallback<List<?>>() {
@Override
@SuppressWarnings({"rawtypes", "deprecation"})
public List<?> doInHibernate(Session session) throws HibernateException {
org.hibernate.Query queryObject = (org.hibernate.Query)
ReflectionUtils.invokeMethod(createQueryMethod, session, queryString);
prepareQuery(queryObject);
for (int i = 0; i < values.length; i++) {
applyNamedParameterToQuery(queryObject, paramNames[i], values[i]);
}
return queryObject.list();
return nonNull(executeWithNativeSession((HibernateCallback<List<?>>) session -> {
org.hibernate.Query queryObject = queryObject(
ReflectionUtils.invokeMethod(createQueryMethod, session, queryString));
prepareQuery(queryObject);
for (int i = 0; i < values.length; i++) {
applyNamedParameterToQuery(queryObject, paramNames[i], values[i]);
}
});
return queryObject.list();
}));
}
@Override
@SuppressWarnings({"rawtypes", "unchecked", "deprecation"})
public List<?> findByValueBean(final String queryString, final Object valueBean)
throws DataAccessException {
return executeWithNativeSession(new HibernateCallback<List<?>>() {
@Override
@SuppressWarnings({"rawtypes", "deprecation"})
public List<?> doInHibernate(Session session) throws HibernateException {
org.hibernate.Query queryObject = (org.hibernate.Query)
ReflectionUtils.invokeMethod(createQueryMethod, session, queryString);
prepareQuery(queryObject);
queryObject.setProperties(valueBean);
return queryObject.list();
}
});
return nonNull(executeWithNativeSession((HibernateCallback<List<?>>) session -> {
org.hibernate.Query queryObject = queryObject(
ReflectionUtils.invokeMethod(createQueryMethod, session, queryString));
prepareQuery(queryObject);
queryObject.setProperties(valueBean);
return queryObject.list();
}));
}
@@ -958,22 +879,19 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
//-------------------------------------------------------------------------
@Override
public List<?> findByNamedQuery(final String queryName, final Object... values) throws DataAccessException {
return executeWithNativeSession(new HibernateCallback<List<?>>() {
@Override
@SuppressWarnings({"rawtypes", "deprecation"})
public List<?> doInHibernate(Session session) throws HibernateException {
org.hibernate.Query queryObject = (org.hibernate.Query)
ReflectionUtils.invokeMethod(getNamedQueryMethod, session, queryName);
prepareQuery(queryObject);
if (values != null) {
for (int i = 0; i < values.length; i++) {
queryObject.setParameter(i, values[i]);
}
@SuppressWarnings({"rawtypes", "unchecked", "deprecation"})
public List<?> findByNamedQuery(final String queryName, @Nullable final Object... values) throws DataAccessException {
return nonNull(executeWithNativeSession((HibernateCallback<List<?>>) session -> {
org.hibernate.Query queryObject = queryObject(
ReflectionUtils.invokeMethod(getNamedQueryMethod, session, queryName));
prepareQuery(queryObject);
if (values != null) {
for (int i = 0; i < values.length; i++) {
queryObject.setParameter(i, values[i]);
}
return queryObject.list();
}
});
return queryObject.list();
}));
}
@Override
@@ -984,45 +902,39 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
}
@Override
@SuppressWarnings({"rawtypes", "unchecked", "deprecation"})
public List<?> findByNamedQueryAndNamedParam(
final String queryName, final String[] paramNames, final Object[] values)
final String queryName, @Nullable final String[] paramNames, @Nullable final Object[] values)
throws DataAccessException {
if (values != null && (paramNames == null || paramNames.length != values.length)) {
throw new IllegalArgumentException("Length of paramNames array must match length of values array");
}
return executeWithNativeSession(new HibernateCallback<List<?>>() {
@Override
@SuppressWarnings({"rawtypes", "deprecation"})
public List<?> doInHibernate(Session session) throws HibernateException {
org.hibernate.Query queryObject = (org.hibernate.Query)
ReflectionUtils.invokeMethod(getNamedQueryMethod, session, queryName);
prepareQuery(queryObject);
if (values != null) {
for (int i = 0; i < values.length; i++) {
applyNamedParameterToQuery(queryObject, paramNames[i], values[i]);
}
return nonNull(executeWithNativeSession((HibernateCallback<List<?>>) session -> {
org.hibernate.Query queryObject = (org.hibernate.Query)
nonNull(ReflectionUtils.invokeMethod(getNamedQueryMethod, session, queryName));
prepareQuery(queryObject);
if (values != null) {
for (int i = 0; i < values.length; i++) {
applyNamedParameterToQuery(queryObject, paramNames[i], values[i]);
}
return queryObject.list();
}
});
return queryObject.list();
}));
}
@Override
@SuppressWarnings({"rawtypes", "unchecked", "deprecation"})
public List<?> findByNamedQueryAndValueBean(final String queryName, final Object valueBean)
throws DataAccessException {
return executeWithNativeSession(new HibernateCallback<List<?>>() {
@Override
@SuppressWarnings({"rawtypes", "deprecation"})
public List<?> doInHibernate(Session session) throws HibernateException {
org.hibernate.Query queryObject = (org.hibernate.Query)
ReflectionUtils.invokeMethod(getNamedQueryMethod, session, queryName);
prepareQuery(queryObject);
queryObject.setProperties(valueBean);
return queryObject.list();
}
});
return nonNull(executeWithNativeSession((HibernateCallback<List<?>>) session -> {
org.hibernate.Query queryObject = queryObject(
ReflectionUtils.invokeMethod(getNamedQueryMethod, session, queryName));
prepareQuery(queryObject);
queryObject.setProperties(valueBean);
return queryObject.list();
}));
}
@@ -1036,24 +948,22 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
}
@Override
@SuppressWarnings("unchecked")
public List<?> findByCriteria(final DetachedCriteria criteria, final int firstResult, final int maxResults)
throws DataAccessException {
Assert.notNull(criteria, "DetachedCriteria must not be null");
return executeWithNativeSession(new HibernateCallback<List<?>>() {
@Override
public List<?> doInHibernate(Session session) throws HibernateException {
Criteria executableCriteria = criteria.getExecutableCriteria(session);
prepareCriteria(executableCriteria);
if (firstResult >= 0) {
executableCriteria.setFirstResult(firstResult);
}
if (maxResults > 0) {
executableCriteria.setMaxResults(maxResults);
}
return executableCriteria.list();
return nonNull(executeWithNativeSession((HibernateCallback<List<?>>) session -> {
Criteria executableCriteria = criteria.getExecutableCriteria(session);
prepareCriteria(executableCriteria);
if (firstResult >= 0) {
executableCriteria.setFirstResult(firstResult);
}
});
if (maxResults > 0) {
executableCriteria.setMaxResults(maxResults);
}
return executableCriteria.list();
}));
}
@Override
@@ -1072,29 +982,25 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
}
@Override
@SuppressWarnings("deprecation")
@SuppressWarnings({"unchecked", "deprecation"})
public <T> List<T> findByExample(
@Nullable final String entityName, final T exampleEntity, final int firstResult, final int maxResults)
throws DataAccessException {
Assert.notNull(exampleEntity, "Example entity must not be null");
return executeWithNativeSession(new HibernateCallback<List<T>>() {
@Override
@SuppressWarnings("unchecked")
public List<T> doInHibernate(Session session) throws HibernateException {
Criteria executableCriteria = (entityName != null ?
session.createCriteria(entityName) : session.createCriteria(exampleEntity.getClass()));
executableCriteria.add(Example.create(exampleEntity));
prepareCriteria(executableCriteria);
if (firstResult >= 0) {
executableCriteria.setFirstResult(firstResult);
}
if (maxResults > 0) {
executableCriteria.setMaxResults(maxResults);
}
return executableCriteria.list();
return nonNull(executeWithNativeSession((HibernateCallback<List<T>>) session -> {
Criteria executableCriteria = (entityName != null ?
session.createCriteria(entityName) : session.createCriteria(exampleEntity.getClass()));
executableCriteria.add(Example.create(exampleEntity));
prepareCriteria(executableCriteria);
if (firstResult >= 0) {
executableCriteria.setFirstResult(firstResult);
}
});
if (maxResults > 0) {
executableCriteria.setMaxResults(maxResults);
}
return executableCriteria.list();
}));
}
@@ -1103,22 +1009,19 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
//-------------------------------------------------------------------------
@Override
public Iterator<?> iterate(final String queryString, final Object... values) throws DataAccessException {
return executeWithNativeSession(new HibernateCallback<Iterator<?>>() {
@Override
@SuppressWarnings({"rawtypes", "deprecation"})
public Iterator<?> doInHibernate(Session session) throws HibernateException {
org.hibernate.Query queryObject = (org.hibernate.Query)
ReflectionUtils.invokeMethod(createQueryMethod, session, queryString);
prepareQuery(queryObject);
if (values != null) {
for (int i = 0; i < values.length; i++) {
queryObject.setParameter(i, values[i]);
}
@SuppressWarnings({"rawtypes", "deprecation"})
public Iterator<?> iterate(final String queryString, @Nullable final Object... values) throws DataAccessException {
return nonNull(executeWithNativeSession((HibernateCallback<Iterator<?>>) session -> {
org.hibernate.Query queryObject = queryObject(
ReflectionUtils.invokeMethod(createQueryMethod, session, queryString));
prepareQuery(queryObject);
if (values != null) {
for (int i = 0; i < values.length; i++) {
queryObject.setParameter(i, values[i]);
}
return queryObject.iterate();
}
});
return queryObject.iterate();
}));
}
@Override
@@ -1132,22 +1035,21 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
}
@Override
public int bulkUpdate(final String queryString, final Object... values) throws DataAccessException {
return executeWithNativeSession(new HibernateCallback<Integer>() {
@Override
@SuppressWarnings({"rawtypes", "deprecation"})
public Integer doInHibernate(Session session) throws HibernateException {
org.hibernate.Query queryObject = (org.hibernate.Query)
ReflectionUtils.invokeMethod(createQueryMethod, session, queryString);
prepareQuery(queryObject);
if (values != null) {
for (int i = 0; i < values.length; i++) {
queryObject.setParameter(i, values[i]);
}
@SuppressWarnings({"rawtypes", "deprecation"})
public int bulkUpdate(final String queryString, @Nullable final Object... values) throws DataAccessException {
Integer result = executeWithNativeSession(session -> {
org.hibernate.Query queryObject = queryObject(
ReflectionUtils.invokeMethod(createQueryMethod, session, queryString));
prepareQuery(queryObject);
if (values != null) {
for (int i = 0; i < values.length; i++) {
queryObject.setParameter(i, values[i]);
}
return queryObject.executeUpdate();
}
return queryObject.executeUpdate();
});
Assert.state(result != null, "No update count");
return result;
}
@@ -1196,7 +1098,7 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
}
SessionHolder sessionHolder =
(SessionHolder) TransactionSynchronizationManager.getResource(getSessionFactory());
(SessionHolder) TransactionSynchronizationManager.getResource(obtainSessionFactory());
if (sessionHolder != null && sessionHolder.hasTimeout()) {
queryObject.setTimeout(sessionHolder.getTimeToLiveInSeconds());
}
@@ -1224,7 +1126,7 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
}
SessionHolder sessionHolder =
(SessionHolder) TransactionSynchronizationManager.getResource(getSessionFactory());
(SessionHolder) TransactionSynchronizationManager.getResource(obtainSessionFactory());
if (sessionHolder != null && sessionHolder.hasTimeout()) {
criteria.setTimeout(sessionHolder.getTimeToLiveInSeconds());
}
@@ -1253,6 +1155,18 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
}
private static <T> T nonNull(@Nullable T result) {
Assert.state(result != null, "No result");
return result;
}
@SuppressWarnings({"rawtypes", "deprecation"})
private static org.hibernate.Query queryObject(@Nullable Object result) {
Assert.state(result != null, "No Hibernate Query");
return (org.hibernate.Query) result;
}
/**
* Invocation handler that suppresses close calls on Hibernate Sessions.
* Also prepares returned Query and Criteria objects.
@@ -1268,6 +1182,7 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
@Override
@SuppressWarnings({"rawtypes", "deprecation"})
@Nullable
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// Invocation on Session interface coming in...

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.
@@ -18,7 +18,6 @@ package org.springframework.orm.hibernate5;
import java.sql.Connection;
import java.sql.ResultSet;
import javax.persistence.PersistenceException;
import javax.sql.DataSource;
@@ -52,6 +51,7 @@ import org.springframework.transaction.support.AbstractPlatformTransactionManage
import org.springframework.transaction.support.DefaultTransactionStatus;
import org.springframework.transaction.support.ResourceTransactionManager;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.Assert;
/**
* {@link org.springframework.transaction.PlatformTransactionManager}
@@ -159,10 +159,23 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
/**
* Return the SessionFactory that this instance should manage transactions for.
*/
@Nullable
public SessionFactory getSessionFactory() {
return this.sessionFactory;
}
/**
* Obtain the SessionFactory for actual use.
* @return the SessionFactory (never {@code null})
* @throws IllegalStateException in case of no SessionFactory set
* @since 5.0
*/
protected final SessionFactory obtainSessionFactory() {
SessionFactory sessionFactory = getSessionFactory();
Assert.state(sessionFactory != null, "No SessionFactory set");
return sessionFactory;
}
/**
* Set the JDBC DataSource that this instance should manage transactions for.
* The DataSource should match the one used by the Hibernate SessionFactory:
@@ -200,6 +213,7 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
/**
* Return the JDBC DataSource that this instance manages transactions for.
*/
@Nullable
public DataSource getDataSource() {
return this.dataSource;
}
@@ -368,7 +382,7 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
@Override
public Object getResourceFactory() {
return getSessionFactory();
return obtainSessionFactory();
}
@Override
@@ -376,8 +390,9 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
HibernateTransactionObject txObject = new HibernateTransactionObject();
txObject.setSavepointAllowed(isNestedTransactionAllowed());
SessionFactory sessionFactory = obtainSessionFactory();
SessionHolder sessionHolder =
(SessionHolder) TransactionSynchronizationManager.getResource(getSessionFactory());
(SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);
if (sessionHolder != null) {
if (logger.isDebugEnabled()) {
logger.debug("Found thread-bound Session [" + sessionHolder.getSession() + "] for Hibernate transaction");
@@ -386,7 +401,7 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
}
else if (this.hibernateManagedSession) {
try {
Session session = this.sessionFactory.getCurrentSession();
Session session = sessionFactory.getCurrentSession();
if (logger.isDebugEnabled()) {
logger.debug("Found Hibernate-managed Session [" + session + "] for Spring-managed transaction");
}
@@ -430,11 +445,11 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
Session session = null;
try {
if (txObject.getSessionHolder() == null || txObject.getSessionHolder().isSynchronizedWithTransaction()) {
if (!txObject.hasSessionHolder() || txObject.getSessionHolder().isSynchronizedWithTransaction()) {
Interceptor entityInterceptor = getEntityInterceptor();
Session newSession = (entityInterceptor != null ?
getSessionFactory().withOptions().interceptor(entityInterceptor).openSession() :
getSessionFactory().openSession());
obtainSessionFactory().withOptions().interceptor(entityInterceptor).openSession() :
obtainSessionFactory().openSession());
if (logger.isDebugEnabled()) {
logger.debug("Opened new Session [" + newSession + "] for Hibernate transaction");
}
@@ -522,7 +537,7 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
// Bind the session holder to the thread.
if (txObject.isNewSessionHolder()) {
TransactionSynchronizationManager.bindResource(getSessionFactory(), txObject.getSessionHolder());
TransactionSynchronizationManager.bindResource(obtainSessionFactory(), txObject.getSessionHolder());
}
txObject.getSessionHolder().setSynchronizedWithTransaction(true);
}
@@ -530,7 +545,7 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
catch (Throwable ex) {
if (txObject.isNewSession()) {
try {
if (session.getTransaction().getStatus() == TransactionStatus.ACTIVE) {
if (session != null && session.getTransaction().getStatus() == TransactionStatus.ACTIVE) {
session.getTransaction().rollback();
}
}
@@ -551,7 +566,7 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
HibernateTransactionObject txObject = (HibernateTransactionObject) transaction;
txObject.setSessionHolder(null);
SessionHolder sessionHolder =
(SessionHolder) TransactionSynchronizationManager.unbindResource(getSessionFactory());
(SessionHolder) TransactionSynchronizationManager.unbindResource(obtainSessionFactory());
txObject.setConnectionHolder(null);
ConnectionHolder connectionHolder = null;
if (getDataSource() != null) {
@@ -561,15 +576,17 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
}
@Override
protected void doResume(Object transaction, Object suspendedResources) {
protected void doResume(@Nullable Object transaction, Object suspendedResources) {
SessionFactory sessionFactory = obtainSessionFactory();
SuspendedResourcesHolder resourcesHolder = (SuspendedResourcesHolder) suspendedResources;
if (TransactionSynchronizationManager.hasResource(getSessionFactory())) {
if (TransactionSynchronizationManager.hasResource(sessionFactory)) {
// From non-transactional code running in active transaction synchronization
// -> can be safely removed, will be closed on transaction completion.
TransactionSynchronizationManager.unbindResource(getSessionFactory());
TransactionSynchronizationManager.unbindResource(sessionFactory);
}
TransactionSynchronizationManager.bindResource(getSessionFactory(), resourcesHolder.getSessionHolder());
if (getDataSource() != null) {
TransactionSynchronizationManager.bindResource(sessionFactory, resourcesHolder.getSessionHolder());
if (getDataSource() != null && resourcesHolder.getConnectionHolder() != null) {
TransactionSynchronizationManager.bindResource(getDataSource(), resourcesHolder.getConnectionHolder());
}
}
@@ -577,12 +594,15 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
@Override
protected void doCommit(DefaultTransactionStatus status) {
HibernateTransactionObject txObject = (HibernateTransactionObject) status.getTransaction();
Transaction hibTx = txObject.getSessionHolder().getTransaction();
Assert.state(hibTx != null, "No Hibernate transaction");
if (status.isDebug()) {
logger.debug("Committing Hibernate transaction on Session [" +
txObject.getSessionHolder().getSession() + "]");
}
try {
txObject.getSessionHolder().getTransaction().commit();
hibTx.commit();
}
catch (org.hibernate.TransactionException ex) {
// assumably from commit call to the underlying JDBC connection
@@ -603,12 +623,15 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
@Override
protected void doRollback(DefaultTransactionStatus status) {
HibernateTransactionObject txObject = (HibernateTransactionObject) status.getTransaction();
Transaction hibTx = txObject.getSessionHolder().getTransaction();
Assert.state(hibTx != null, "No Hibernate transaction");
if (status.isDebug()) {
logger.debug("Rolling back Hibernate transaction on Session [" +
txObject.getSessionHolder().getSession() + "]");
}
try {
txObject.getSessionHolder().getTransaction().rollback();
hibTx.rollback();
}
catch (org.hibernate.TransactionException ex) {
throw new TransactionSystemException("Could not roll back Hibernate transaction", ex);
@@ -649,7 +672,7 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
// Remove the session holder from the thread.
if (txObject.isNewSessionHolder()) {
TransactionSynchronizationManager.unbindResource(getSessionFactory());
TransactionSynchronizationManager.unbindResource(obtainSessionFactory());
}
// Remove the JDBC connection holder from the thread, if exposed.
@@ -792,9 +815,14 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
}
public SessionHolder getSessionHolder() {
Assert.state(this.sessionHolder != null, "No SessionHolder available");
return this.sessionHolder;
}
public boolean hasSessionHolder() {
return (this.sessionHolder != null);
}
public boolean isNewSessionHolder() {
return this.newSessionHolder;
}
@@ -807,6 +835,7 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
this.previousHoldability = previousHoldability;
}
@Nullable
public Integer getPreviousHoldability() {
return this.previousHoldability;
}
@@ -861,7 +890,7 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
private final ConnectionHolder connectionHolder;
private SuspendedResourcesHolder(SessionHolder sessionHolder, ConnectionHolder conHolder) {
private SuspendedResourcesHolder(SessionHolder sessionHolder, @Nullable ConnectionHolder conHolder) {
this.sessionHolder = sessionHolder;
this.connectionHolder = conHolder;
}
@@ -870,6 +899,7 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
return this.sessionHolder;
}
@Nullable
private ConnectionHolder getConnectionHolder() {
return this.connectionHolder;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.TreeSet;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
import javax.persistence.Embeddable;
@@ -323,10 +322,10 @@ public class LocalSessionFactoryBuilder extends Configuration {
try {
ClassLoader cl = this.resourcePatternResolver.getClassLoader();
for (String className : entityClassNames) {
addAnnotatedClass(cl.loadClass(className));
addAnnotatedClass(ClassUtils.forName(className, cl));
}
for (String className : converterClassNames) {
addAttributeConverter((Class<? extends AttributeConverter<?, ?>>) cl.loadClass(className));
addAttributeConverter((Class<? extends AttributeConverter<?, ?>>) ClassUtils.forName(className, cl));
}
for (String packageName : packageNames) {
addPackage(packageName);

View File

@@ -18,7 +18,6 @@ package org.springframework.orm.hibernate5;
import java.lang.reflect.Method;
import java.util.Map;
import javax.persistence.PersistenceException;
import javax.sql.DataSource;
@@ -123,7 +122,9 @@ public abstract class SessionFactoryUtils {
* @since 4.3
*/
static FlushMode getFlushMode(Session session) {
return (FlushMode) ReflectionUtils.invokeMethod(getFlushMode, session);
FlushMode flushMode = (FlushMode) ReflectionUtils.invokeMethod(getFlushMode, session);
Assert.state(flushMode != null, "No FlushMode from Session");
return flushMode;
}
/**
@@ -188,9 +189,11 @@ public abstract class SessionFactoryUtils {
Method getProperties = ClassUtils.getMethodIfAvailable(sessionFactory.getClass(), "getProperties");
if (getProperties != null) {
Map<?, ?> props = (Map<?, ?>) ReflectionUtils.invokeMethod(getProperties, sessionFactory);
Object dataSourceValue = props.get(Environment.DATASOURCE);
if (dataSourceValue instanceof DataSource) {
return (DataSource) dataSourceValue;
if (props != null) {
Object dataSourceValue = props.get(Environment.DATASOURCE);
if (dataSourceValue instanceof DataSource) {
return (DataSource) dataSourceValue;
}
}
}
if (sessionFactory instanceof SessionFactoryImplementor) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2017 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.
@@ -20,6 +20,7 @@ import org.hibernate.FlushMode;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.springframework.lang.Nullable;
import org.springframework.transaction.support.ResourceHolderSupport;
import org.springframework.util.Assert;
@@ -37,7 +38,7 @@ import org.springframework.util.Assert;
*/
public class SessionHolder extends ResourceHolderSupport {
private Session session;
private final Session session;
private Transaction transaction;
@@ -49,6 +50,7 @@ public class SessionHolder extends ResourceHolderSupport {
this.session = session;
}
public Session getSession() {
return this.session;
}
@@ -57,6 +59,7 @@ public class SessionHolder extends ResourceHolderSupport {
this.transaction = transaction;
}
@Nullable
public Transaction getTransaction() {
return this.transaction;
}
@@ -65,6 +68,7 @@ public class SessionHolder extends ResourceHolderSupport {
this.previousFlushMode = previousFlushMode;
}
@Nullable
public FlushMode getPreviousFlushMode() {
return this.previousFlushMode;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2017 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.
@@ -21,7 +21,9 @@ import org.hibernate.SessionFactory;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.dao.support.DaoSupport;
import org.springframework.lang.Nullable;
import org.springframework.orm.hibernate5.HibernateTemplate;
import org.springframework.util.Assert;
/**
* Convenient super class for Hibernate-based data access objects.
@@ -84,6 +86,7 @@ public abstract class HibernateDaoSupport extends DaoSupport {
/**
* Return the Hibernate SessionFactory used by this DAO.
*/
@Nullable
public final SessionFactory getSessionFactory() {
return (this.hibernateTemplate != null ? this.hibernateTemplate.getSessionFactory() : null);
}
@@ -126,7 +129,9 @@ public abstract class HibernateDaoSupport extends DaoSupport {
* @see SessionFactory#getCurrentSession()
*/
protected final Session currentSession() throws DataAccessResourceFailureException {
return getSessionFactory().getCurrentSession();
SessionFactory sessionFactory = getSessionFactory();
Assert.state(sessionFactory != null, "No SessionFactory set");
return sessionFactory.getCurrentSession();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.
@@ -32,6 +32,7 @@ import org.springframework.orm.hibernate5.SessionFactoryUtils;
import org.springframework.orm.hibernate5.SessionHolder;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.async.CallableProcessingInterceptor;
import org.springframework.web.context.request.async.WebAsyncManager;
import org.springframework.web.context.request.async.WebAsyncUtils;
import org.springframework.web.context.support.WebApplicationContextUtils;
@@ -212,10 +213,11 @@ public class OpenSessionInViewFilter extends OncePerRequestFilter {
}
private boolean applySessionBindingInterceptor(WebAsyncManager asyncManager, String key) {
if (asyncManager.getCallableInterceptor(key) == null) {
CallableProcessingInterceptor cpi = asyncManager.getCallableInterceptor(key);
if (cpi == null) {
return false;
}
((AsyncRequestInterceptor) asyncManager.getCallableInterceptor(key)).bindSession();
((AsyncRequestInterceptor) cpi).bindSession();
return true;
}

View File

@@ -32,6 +32,7 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
import org.springframework.ui.ModelMap;
import org.springframework.web.context.request.AsyncWebRequestInterceptor;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.context.request.async.CallableProcessingInterceptor;
import org.springframework.web.context.request.async.WebAsyncManager;
import org.springframework.web.context.request.async.WebAsyncUtils;
@@ -202,10 +203,11 @@ public class OpenSessionInViewInterceptor implements AsyncWebRequestInterceptor
}
private boolean applySessionBindingInterceptor(WebAsyncManager asyncManager, String key) {
if (asyncManager.getCallableInterceptor(key) == null) {
CallableProcessingInterceptor cpi = asyncManager.getCallableInterceptor(key);
if (cpi == null) {
return false;
}
((AsyncRequestInterceptor) asyncManager.getCallableInterceptor(key)).bindSession();
((AsyncRequestInterceptor) cpi).bindSession();
return true;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.
@@ -25,9 +25,11 @@ import org.hibernate.SessionFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.lang.Nullable;
import org.springframework.orm.hibernate5.SessionFactoryUtils;
import org.springframework.orm.hibernate5.SessionHolder;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.Assert;
/**
* Simple AOP Alliance {@link MethodInterceptor} implementation that binds a new
@@ -61,6 +63,7 @@ public class OpenSessionInterceptor implements MethodInterceptor, InitializingBe
/**
* Return the Hibernate SessionFactory that should be used to create Hibernate Sessions.
*/
@Nullable
public SessionFactory getSessionFactory() {
return this.sessionFactory;
}
@@ -76,9 +79,11 @@ public class OpenSessionInterceptor implements MethodInterceptor, InitializingBe
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
SessionFactory sf = getSessionFactory();
Assert.state(sf != null, "No SessionFactory set");
if (!TransactionSynchronizationManager.hasResource(sf)) {
// New Session to be bound for the current method's scope...
Session session = openSession();
Session session = openSession(sf);
try {
TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session));
return invocation.proceed();
@@ -100,12 +105,13 @@ public class OpenSessionInterceptor implements MethodInterceptor, InitializingBe
* method and sets the {@link Session}'s flush mode to "MANUAL".
* @return the Session to use
* @throws DataAccessResourceFailureException if the Session could not be created
* @since 4.3.9
* @see FlushMode#MANUAL
*/
@SuppressWarnings("deprecation")
protected Session openSession() throws DataAccessResourceFailureException {
protected Session openSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException {
try {
Session session = getSessionFactory().openSession();
Session session = sessionFactory.openSession();
session.setFlushMode(FlushMode.MANUAL);
return session;
}

View File

@@ -33,7 +33,6 @@ import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceException;
@@ -57,7 +56,6 @@ import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.support.PersistenceExceptionTranslator;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
@@ -193,7 +191,7 @@ public abstract class AbstractEntityManagerFactoryBean implements
* @see javax.persistence.Persistence#createEntityManagerFactory(String, java.util.Map)
* @see javax.persistence.spi.PersistenceProvider#createContainerEntityManagerFactory(javax.persistence.spi.PersistenceUnitInfo, java.util.Map)
*/
public void setJpaPropertyMap(Map<String, ?> jpaProperties) {
public void setJpaPropertyMap(@Nullable Map<String, ?> jpaProperties) {
if (jpaProperties != null) {
this.jpaPropertyMap.putAll(jpaProperties);
}
@@ -300,7 +298,7 @@ public abstract class AbstractEntityManagerFactoryBean implements
}
@Override
public void setBeanClassLoader(@Nullable ClassLoader classLoader) {
public void setBeanClassLoader(ClassLoader classLoader) {
this.beanClassLoader = classLoader;
}
@@ -372,10 +370,6 @@ public abstract class AbstractEntityManagerFactoryBean implements
private EntityManagerFactory buildNativeEntityManagerFactory() {
EntityManagerFactory emf = createNativeEntityManagerFactory();
if (emf == null) {
throw new IllegalStateException(
"JPA PersistenceProvider returned null EntityManagerFactory - check your JPA provider setup!");
}
if (this.jpaVendorAdapter != null) {
this.jpaVendorAdapter.postProcessEntityManagerFactory(emf);
}
@@ -389,10 +383,11 @@ public abstract class AbstractEntityManagerFactoryBean implements
* Create a proxy of the given EntityManagerFactory. We do this to be able
* to return transaction-aware proxies for application-managed
* EntityManagers, and to introduce the NamedEntityManagerFactory interface
* @param emf EntityManagerFactory as returned by the persistence provider
* @param emf EntityManagerFactory as returned by the persistence provider,
* if initialized already
* @return proxy entity manager
*/
protected EntityManagerFactory createEntityManagerFactoryProxy(EntityManagerFactory emf) {
protected EntityManagerFactory createEntityManagerFactoryProxy(@Nullable EntityManagerFactory emf) {
Set<Class<?>> ifcs = new LinkedHashSet<>();
if (this.entityManagerFactoryInterface != null) {
ifcs.add(this.entityManagerFactoryInterface);
@@ -427,7 +422,7 @@ public abstract class AbstractEntityManagerFactoryBean implements
* Delegate an incoming invocation from the proxy, dispatching to EntityManagerFactoryInfo
* or the native EntityManagerFactory accordingly.
*/
Object invokeProxyMethod(Method method, Object[] args) throws Throwable {
Object invokeProxyMethod(Method method, @Nullable Object[] args) throws Throwable {
if (method.getDeclaringClass().isAssignableFrom(EntityManagerFactoryInfo.class)) {
return method.invoke(this, args);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.
@@ -19,7 +19,6 @@ package org.springframework.orm.jpa;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
@@ -68,10 +67,23 @@ public abstract class EntityManagerFactoryAccessor implements BeanFactoryAware {
* Return the JPA EntityManagerFactory that should be used to create
* EntityManagers.
*/
@Nullable
public EntityManagerFactory getEntityManagerFactory() {
return this.entityManagerFactory;
}
/**
* Obtain the EntityManagerFactory for actual use.
* @return the EntityManagerFactory (never {@code null})
* @throws IllegalStateException in case of no EntityManagerFactory set
* @since 5.0
*/
protected final EntityManagerFactory obtainEntityManagerFactory() {
EntityManagerFactory emf = getEntityManagerFactory();
Assert.state(emf != null, "No EntityManagerFactory set");
return emf;
}
/**
* Set the name of the persistence unit to access the EntityManagerFactory for.
* <p>This is an alternative to specifying the EntityManagerFactory by direct reference,
@@ -151,8 +163,7 @@ public abstract class EntityManagerFactoryAccessor implements BeanFactoryAware {
* @see javax.persistence.EntityManagerFactory#createEntityManager(java.util.Map)
*/
protected EntityManager createEntityManager() throws IllegalStateException {
EntityManagerFactory emf = getEntityManagerFactory();
Assert.state(emf != null, "No EntityManagerFactory specified");
EntityManagerFactory emf = obtainEntityManagerFactory();
Map<String, Object> properties = getJpaPropertyMap();
return (!CollectionUtils.isEmpty(properties) ? emf.createEntityManager(properties) : emf.createEntityManager());
}
@@ -166,8 +177,7 @@ public abstract class EntityManagerFactoryAccessor implements BeanFactoryAware {
*/
@Nullable
protected EntityManager getTransactionalEntityManager() throws IllegalStateException{
EntityManagerFactory emf = getEntityManagerFactory();
Assert.state(emf != null, "No EntityManagerFactory specified");
EntityManagerFactory emf = obtainEntityManagerFactory();
return EntityManagerFactoryUtils.getTransactionalEntityManager(emf, getJpaPropertyMap());
}

View File

@@ -196,7 +196,8 @@ public abstract class EntityManagerFactoryUtils {
*/
@Nullable
public static EntityManager doGetTransactionalEntityManager(
EntityManagerFactory emf, @Nullable Map<?, ?> properties, boolean synchronizedWithTransaction) throws PersistenceException {
EntityManagerFactory emf, @Nullable Map<?, ?> properties, boolean synchronizedWithTransaction)
throws PersistenceException {
Assert.notNull(emf, "No EntityManagerFactory specified");
@@ -449,7 +450,7 @@ public abstract class EntityManagerFactoryUtils {
private final boolean newEntityManager;
public TransactionalEntityManagerSynchronization(
EntityManagerHolder emHolder, EntityManagerFactory emf, Object txData, boolean newEm) {
EntityManagerHolder emHolder, EntityManagerFactory emf, @Nullable Object txData, boolean newEm) {
super(emHolder, emf);
this.transactionData = txData;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2007 the original author or authors.
* Copyright 2002-2017 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.
@@ -18,6 +18,7 @@ package org.springframework.orm.jpa;
import javax.persistence.EntityManager;
import org.springframework.lang.Nullable;
import org.springframework.transaction.SavepointManager;
import org.springframework.transaction.support.ResourceHolderSupport;
import org.springframework.util.Assert;
@@ -65,10 +66,12 @@ public class EntityManagerHolder extends ResourceHolderSupport {
this.savepointManager = savepointManager;
}
@Nullable
protected SavepointManager getSavepointManager() {
return this.savepointManager;
}
@Override
public void clear() {
super.clear();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.
@@ -24,7 +24,6 @@ import java.lang.reflect.Proxy;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
@@ -258,7 +257,7 @@ public abstract class ExtendedEntityManagerCreator {
private final boolean synchronizedWithTransaction;
private ExtendedEntityManagerInvocationHandler(EntityManager target,
PersistenceExceptionTranslator exceptionTranslator, Boolean jta,
@Nullable PersistenceExceptionTranslator exceptionTranslator, @Nullable Boolean jta,
boolean containerManaged, boolean synchronizedWithTransaction) {
this.target = target;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.
@@ -17,7 +17,6 @@
package org.springframework.orm.jpa;
import java.sql.SQLException;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceException;
@@ -104,7 +103,7 @@ public interface JpaDialect extends PersistenceExceptionTranslator {
* @see #cleanupTransaction
*/
@Nullable
Object prepareTransaction(EntityManager entityManager, boolean readOnly, String name)
Object prepareTransaction(EntityManager entityManager, boolean readOnly, @Nullable String name)
throws PersistenceException;
/**

View File

@@ -50,6 +50,7 @@ import org.springframework.transaction.support.DefaultTransactionStatus;
import org.springframework.transaction.support.DelegatingTransactionDefinition;
import org.springframework.transaction.support.ResourceTransactionManager;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
/**
@@ -157,10 +158,23 @@ public class JpaTransactionManager extends AbstractPlatformTransactionManager
/**
* Return the EntityManagerFactory that this instance should manage transactions for.
*/
@Nullable
public EntityManagerFactory getEntityManagerFactory() {
return this.entityManagerFactory;
}
/**
* Obtain the EntityManagerFactory for actual use.
* @return the EntityManagerFactory (never {@code null})
* @throws IllegalStateException in case of no EntityManagerFactory set
* @since 5.0
*/
protected final EntityManagerFactory obtainEntityManagerFactory() {
EntityManagerFactory emf = getEntityManagerFactory();
Assert.state(emf != null, "No EntityManagerFactory set");
return emf;
}
/**
* Set the name of the persistence unit to manage transactions for.
* <p>This is an alternative to specifying the EntityManagerFactory by direct reference,
@@ -252,6 +266,7 @@ public class JpaTransactionManager extends AbstractPlatformTransactionManager
/**
* Return the JDBC DataSource that this instance manages transactions for.
*/
@Nullable
public DataSource getDataSource() {
return this.dataSource;
}
@@ -267,7 +282,7 @@ public class JpaTransactionManager extends AbstractPlatformTransactionManager
* @see JpaDialect#beginTransaction
* @see JpaDialect#getJdbcConnection
*/
public void setJpaDialect(JpaDialect jpaDialect) {
public void setJpaDialect(@Nullable JpaDialect jpaDialect) {
this.jpaDialect = (jpaDialect != null ? jpaDialect : new DefaultJpaDialect());
}
@@ -321,7 +336,7 @@ public class JpaTransactionManager extends AbstractPlatformTransactionManager
@Override
public Object getResourceFactory() {
return getEntityManagerFactory();
return obtainEntityManagerFactory();
}
@Override
@@ -330,7 +345,7 @@ public class JpaTransactionManager extends AbstractPlatformTransactionManager
txObject.setSavepointAllowed(isNestedTransactionAllowed());
EntityManagerHolder emHolder = (EntityManagerHolder)
TransactionSynchronizationManager.getResource(getEntityManagerFactory());
TransactionSynchronizationManager.getResource(obtainEntityManagerFactory());
if (emHolder != null) {
if (logger.isDebugEnabled()) {
logger.debug("Found thread-bound EntityManager [" + emHolder.getEntityManager() +
@@ -366,7 +381,7 @@ public class JpaTransactionManager extends AbstractPlatformTransactionManager
}
try {
if (txObject.getEntityManagerHolder() == null ||
if (!txObject.hasEntityManagerHolder() ||
txObject.getEntityManagerHolder().isSynchronizedWithTransaction()) {
EntityManager newEm = createEntityManagerForTransaction();
if (logger.isDebugEnabled()) {
@@ -419,7 +434,7 @@ public class JpaTransactionManager extends AbstractPlatformTransactionManager
// Bind the entity manager holder to the thread.
if (txObject.isNewEntityManagerHolder()) {
TransactionSynchronizationManager.bindResource(
getEntityManagerFactory(), txObject.getEntityManagerHolder());
obtainEntityManagerFactory(), txObject.getEntityManagerHolder());
}
txObject.getEntityManagerHolder().setSynchronizedWithTransaction(true);
}
@@ -442,7 +457,7 @@ public class JpaTransactionManager extends AbstractPlatformTransactionManager
* @see EntityManagerFactoryInfo#getNativeEntityManagerFactory()
*/
protected EntityManager createEntityManagerForTransaction() {
EntityManagerFactory emf = getEntityManagerFactory();
EntityManagerFactory emf = obtainEntityManagerFactory();
if (emf instanceof EntityManagerFactoryInfo) {
emf = ((EntityManagerFactoryInfo) emf).getNativeEntityManagerFactory();
}
@@ -479,7 +494,7 @@ public class JpaTransactionManager extends AbstractPlatformTransactionManager
JpaTransactionObject txObject = (JpaTransactionObject) transaction;
txObject.setEntityManagerHolder(null, false);
EntityManagerHolder entityManagerHolder = (EntityManagerHolder)
TransactionSynchronizationManager.unbindResource(getEntityManagerFactory());
TransactionSynchronizationManager.unbindResource(obtainEntityManagerFactory());
txObject.setConnectionHolder(null);
ConnectionHolder connectionHolder = null;
if (getDataSource() != null && TransactionSynchronizationManager.hasResource(getDataSource())) {
@@ -489,10 +504,10 @@ public class JpaTransactionManager extends AbstractPlatformTransactionManager
}
@Override
protected void doResume(Object transaction, Object suspendedResources) {
protected void doResume(@Nullable Object transaction, Object suspendedResources) {
SuspendedResourcesHolder resourcesHolder = (SuspendedResourcesHolder) suspendedResources;
TransactionSynchronizationManager.bindResource(
getEntityManagerFactory(), resourcesHolder.getEntityManagerHolder());
obtainEntityManagerFactory(), resourcesHolder.getEntityManagerHolder());
if (getDataSource() != null && resourcesHolder.getConnectionHolder() != null) {
TransactionSynchronizationManager.bindResource(getDataSource(), resourcesHolder.getConnectionHolder());
}
@@ -576,12 +591,12 @@ public class JpaTransactionManager extends AbstractPlatformTransactionManager
// (Could have been removed by EntityManagerFactoryUtils in order
// to replace it with an unsynchronized EntityManager).
if (txObject.isNewEntityManagerHolder()) {
TransactionSynchronizationManager.unbindResourceIfPossible(getEntityManagerFactory());
TransactionSynchronizationManager.unbindResourceIfPossible(obtainEntityManagerFactory());
}
txObject.getEntityManagerHolder().clear();
// Remove the JDBC connection holder from the thread, if exposed.
if (txObject.hasConnectionHolder()) {
if (getDataSource() != null && txObject.hasConnectionHolder()) {
TransactionSynchronizationManager.unbindResource(getDataSource());
try {
getJpaDialect().releaseJdbcConnection(txObject.getConnectionHolder().getConnectionHandle(),
@@ -631,6 +646,10 @@ public class JpaTransactionManager extends AbstractPlatformTransactionManager
return this.entityManagerHolder;
}
public boolean hasEntityManagerHolder() {
return (this.entityManagerHolder != null);
}
public boolean isNewEntityManagerHolder() {
return this.newEntityManagerHolder;
}
@@ -639,7 +658,7 @@ public class JpaTransactionManager extends AbstractPlatformTransactionManager
return (this.entityManagerHolder != null && this.entityManagerHolder.isTransactionActive());
}
public void setTransactionData(Object transactionData) {
public void setTransactionData(@Nullable Object transactionData) {
this.transactionData = transactionData;
this.entityManagerHolder.setTransactionActive(true);
if (transactionData instanceof SavepointManager) {
@@ -722,7 +741,7 @@ public class JpaTransactionManager extends AbstractPlatformTransactionManager
private final ConnectionHolder connectionHolder;
private SuspendedResourcesHolder(EntityManagerHolder emHolder, ConnectionHolder conHolder) {
private SuspendedResourcesHolder(EntityManagerHolder emHolder, @Nullable ConnectionHolder conHolder) {
this.entityManagerHolder = emHolder;
this.connectionHolder = conHolder;
}
@@ -731,6 +750,7 @@ public class JpaTransactionManager extends AbstractPlatformTransactionManager
return this.entityManagerHolder;
}
@Nullable
private ConnectionHolder getConnectionHolder() {
return this.connectionHolder;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.
@@ -312,7 +312,7 @@ public class LocalContainerEntityManagerFactoryBean extends AbstractEntityManage
}
@Override
public void setResourceLoader(@Nullable ResourceLoader resourceLoader) {
public void setResourceLoader(ResourceLoader resourceLoader) {
this.internalPersistenceUnitManager.setResourceLoader(resourceLoader);
}
@@ -328,8 +328,10 @@ public class LocalContainerEntityManagerFactoryBean extends AbstractEntityManage
this.persistenceUnitInfo = determinePersistenceUnitInfo(managerToUse);
JpaVendorAdapter jpaVendorAdapter = getJpaVendorAdapter();
if (jpaVendorAdapter != null && this.persistenceUnitInfo instanceof SmartPersistenceUnitInfo) {
((SmartPersistenceUnitInfo) this.persistenceUnitInfo).setPersistenceProviderPackageName(
jpaVendorAdapter.getPersistenceProviderRootPackage());
String rootPackage = jpaVendorAdapter.getPersistenceProviderRootPackage();
if (rootPackage != null) {
((SmartPersistenceUnitInfo) this.persistenceUnitInfo).setPersistenceProviderPackageName(rootPackage);
}
}
PersistenceProvider provider = getPersistenceProvider();

View File

@@ -26,7 +26,6 @@ import java.lang.reflect.Proxy;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Query;
@@ -187,7 +186,8 @@ public abstract class SharedEntityManagerCreator {
private transient volatile ClassLoader proxyClassLoader;
public SharedEntityManagerInvocationHandler(
EntityManagerFactory target, Map<?, ?> properties, boolean synchronizedWithTransaction) {
EntityManagerFactory target, @Nullable Map<?, ?> properties, boolean synchronizedWithTransaction) {
this.targetFactory = target;
this.properties = properties;
this.synchronizedWithTransaction = synchronizedWithTransaction;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.
@@ -25,7 +25,6 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.persistence.Converter;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
@@ -306,7 +305,7 @@ public class DefaultPersistenceUnitManager
* @see #setDataSources
* @see #setDefaultDataSource
*/
public void setDataSourceLookup(DataSourceLookup dataSourceLookup) {
public void setDataSourceLookup(@Nullable DataSourceLookup dataSourceLookup) {
this.dataSourceLookup = (dataSourceLookup != null ? dataSourceLookup : new JndiDataSourceLookup());
}
@@ -315,6 +314,7 @@ public class DefaultPersistenceUnitManager
* persistence provider, resolving data source names in {@code persistence.xml}
* against Spring-managed DataSource instances.
*/
@Nullable
public DataSourceLookup getDataSourceLookup() {
return this.dataSourceLookup;
}
@@ -336,6 +336,7 @@ public class DefaultPersistenceUnitManager
* Return the JDBC DataSource that the JPA persistence provider is supposed to use
* for accessing the database if none has been specified in {@code persistence.xml}.
*/
@Nullable
public DataSource getDefaultDataSource() {
return this.defaultDataSource;
}
@@ -357,6 +358,7 @@ public class DefaultPersistenceUnitManager
* Return the JTA-aware DataSource that the JPA persistence provider is supposed to use
* for accessing the database if none has been specified in {@code persistence.xml}.
*/
@Nullable
public DataSource getDefaultJtaDataSource() {
return this.defaultJtaDataSource;
}
@@ -375,6 +377,7 @@ public class DefaultPersistenceUnitManager
* Return the PersistenceUnitPostProcessors to be applied to each
* PersistenceUnitInfo that has been parsed by this manager.
*/
@Nullable
public PersistenceUnitPostProcessor[] getPersistenceUnitPostProcessors() {
return this.persistenceUnitPostProcessors;
}
@@ -406,12 +409,13 @@ public class DefaultPersistenceUnitManager
* Return the Spring LoadTimeWeaver to use for class instrumentation according
* to the JPA class transformer contract.
*/
@Nullable
public LoadTimeWeaver getLoadTimeWeaver() {
return this.loadTimeWeaver;
}
@Override
public void setResourceLoader(@Nullable ResourceLoader resourceLoader) {
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
this.componentsIndex = CandidateComponentsIndexLoader.loadIndex(resourceLoader.getClassLoader());
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.
@@ -26,6 +26,7 @@ import javax.persistence.spi.ClassTransformer;
import javax.persistence.spi.PersistenceUnitTransactionType;
import javax.sql.DataSource;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
/**
@@ -114,6 +115,7 @@ public class MutablePersistenceUnitInfo implements SmartPersistenceUnitInfo {
}
@Override
@Nullable
public DataSource getJtaDataSource() {
return this.jtaDataSource;
}
@@ -123,6 +125,7 @@ public class MutablePersistenceUnitInfo implements SmartPersistenceUnitInfo {
}
@Override
@Nullable
public DataSource getNonJtaDataSource() {
return this.nonJtaDataSource;
}
@@ -145,11 +148,12 @@ public class MutablePersistenceUnitInfo implements SmartPersistenceUnitInfo {
return this.jarFileUrls;
}
public void setPersistenceUnitRootUrl(URL persistenceUnitRootUrl) {
public void setPersistenceUnitRootUrl(@Nullable URL persistenceUnitRootUrl) {
this.persistenceUnitRootUrl = persistenceUnitRootUrl;
}
@Override
@Nullable
public URL getPersistenceUnitRootUrl() {
return this.persistenceUnitRootUrl;
}
@@ -243,6 +247,7 @@ public class MutablePersistenceUnitInfo implements SmartPersistenceUnitInfo {
this.persistenceProviderPackageName = persistenceProviderPackageName;
}
@Nullable
public String getPersistenceProviderPackageName() {
return this.persistenceProviderPackageName;
}
@@ -253,6 +258,7 @@ public class MutablePersistenceUnitInfo implements SmartPersistenceUnitInfo {
* @see org.springframework.util.ClassUtils#getDefaultClassLoader()
*/
@Override
@Nullable
public ClassLoader getClassLoader() {
return ClassUtils.getDefaultClassLoader();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.
@@ -189,8 +189,8 @@ final class PersistenceUnitReader {
/**
* Parse the unit info DOM element.
*/
protected SpringPersistenceUnitInfo parsePersistenceUnitInfo(Element persistenceUnit, String version, URL rootUrl)
throws IOException {
protected SpringPersistenceUnitInfo parsePersistenceUnitInfo(
Element persistenceUnit, String version, @Nullable URL rootUrl) throws IOException {
SpringPersistenceUnitInfo unitInfo = new SpringPersistenceUnitInfo();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2017 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.
@@ -21,6 +21,7 @@ import javax.persistence.spi.ClassTransformer;
import org.springframework.core.DecoratingClassLoader;
import org.springframework.instrument.classloading.LoadTimeWeaver;
import org.springframework.instrument.classloading.SimpleThrowawayClassLoader;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -56,8 +57,7 @@ class SpringPersistenceUnitInfo extends MutablePersistenceUnitInfo {
* Initialize this PersistenceUnitInfo with the current class loader
* (instead of with a LoadTimeWeaver).
*/
public void init(ClassLoader classLoader) {
Assert.notNull(classLoader, "ClassLoader must not be null");
public void init(@Nullable ClassLoader classLoader) {
this.classLoader = classLoader;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2017 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.
@@ -60,10 +60,10 @@ class AsyncRequestInterceptor extends CallableProcessingInterceptorAdapter imple
@Override
public <T> void preProcess(NativeWebRequest request, Callable<T> task) {
bindSession();
bindEntityManager();
}
public void bindSession() {
public void bindEntityManager() {
this.timeoutInProgress = false;
TransactionSynchronizationManager.bindResource(this.emFactory, this.emHolder);
}

View File

@@ -32,6 +32,7 @@ import org.springframework.orm.jpa.EntityManagerHolder;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.StringUtils;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.async.CallableProcessingInterceptor;
import org.springframework.web.context.request.async.WebAsyncManager;
import org.springframework.web.context.request.async.WebAsyncUtils;
import org.springframework.web.context.support.WebApplicationContextUtils;
@@ -241,10 +242,11 @@ public class OpenEntityManagerInViewFilter extends OncePerRequestFilter {
}
private boolean applyEntityManagerBindingInterceptor(WebAsyncManager asyncManager, String key) {
if (asyncManager.getCallableInterceptor(key) == null) {
CallableProcessingInterceptor cpi = asyncManager.getCallableInterceptor(key);
if (cpi == null) {
return false;
}
((AsyncRequestInterceptor) asyncManager.getCallableInterceptor(key)).bindSession();
((AsyncRequestInterceptor) cpi).bindEntityManager();
return true;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2017 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.
@@ -17,6 +17,7 @@
package org.springframework.orm.jpa.support;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceException;
import org.springframework.dao.DataAccessException;
@@ -29,6 +30,7 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
import org.springframework.ui.ModelMap;
import org.springframework.web.context.request.AsyncWebRequestInterceptor;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.context.request.async.CallableProcessingInterceptor;
import org.springframework.web.context.request.async.WebAsyncManager;
import org.springframework.web.context.request.async.WebAsyncUtils;
@@ -68,15 +70,15 @@ public class OpenEntityManagerInViewInterceptor extends EntityManagerFactoryAcce
@Override
public void preHandle(WebRequest request) throws DataAccessException {
String participateAttributeName = getParticipateAttributeName();
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
if (asyncManager.hasConcurrentResult()) {
if (applyCallableInterceptor(asyncManager, participateAttributeName)) {
if (applyEntityManagerBindingInterceptor(asyncManager, participateAttributeName)) {
return;
}
}
if (TransactionSynchronizationManager.hasResource(getEntityManagerFactory())) {
EntityManagerFactory emf = obtainEntityManagerFactory();
if (TransactionSynchronizationManager.hasResource(emf)) {
// Do not modify the EntityManager: just mark the request accordingly.
Integer count = (Integer) request.getAttribute(participateAttributeName, WebRequest.SCOPE_REQUEST);
int newCount = (count != null ? count + 1 : 1);
@@ -87,9 +89,9 @@ public class OpenEntityManagerInViewInterceptor extends EntityManagerFactoryAcce
try {
EntityManager em = createEntityManager();
EntityManagerHolder emHolder = new EntityManagerHolder(em);
TransactionSynchronizationManager.bindResource(getEntityManagerFactory(), emHolder);
TransactionSynchronizationManager.bindResource(emf, emHolder);
AsyncRequestInterceptor interceptor = new AsyncRequestInterceptor(getEntityManagerFactory(), emHolder);
AsyncRequestInterceptor interceptor = new AsyncRequestInterceptor(emf, emHolder);
asyncManager.registerCallableInterceptor(participateAttributeName, interceptor);
asyncManager.registerDeferredResultInterceptor(participateAttributeName, interceptor);
}
@@ -107,7 +109,7 @@ public class OpenEntityManagerInViewInterceptor extends EntityManagerFactoryAcce
public void afterCompletion(WebRequest request, @Nullable Exception ex) throws DataAccessException {
if (!decrementParticipateCount(request)) {
EntityManagerHolder emHolder = (EntityManagerHolder)
TransactionSynchronizationManager.unbindResource(getEntityManagerFactory());
TransactionSynchronizationManager.unbindResource(obtainEntityManagerFactory());
logger.debug("Closing JPA EntityManager in OpenEntityManagerInViewInterceptor");
EntityManagerFactoryUtils.closeEntityManager(emHolder.getEntityManager());
}
@@ -132,7 +134,7 @@ public class OpenEntityManagerInViewInterceptor extends EntityManagerFactoryAcce
@Override
public void afterConcurrentHandlingStarted(WebRequest request) {
if (!decrementParticipateCount(request)) {
TransactionSynchronizationManager.unbindResource(getEntityManagerFactory());
TransactionSynchronizationManager.unbindResource(obtainEntityManagerFactory());
}
}
@@ -143,15 +145,16 @@ public class OpenEntityManagerInViewInterceptor extends EntityManagerFactoryAcce
* @see #PARTICIPATE_SUFFIX
*/
protected String getParticipateAttributeName() {
return getEntityManagerFactory().toString() + PARTICIPATE_SUFFIX;
return obtainEntityManagerFactory().toString() + PARTICIPATE_SUFFIX;
}
private boolean applyCallableInterceptor(WebAsyncManager asyncManager, String key) {
if (asyncManager.getCallableInterceptor(key) == null) {
private boolean applyEntityManagerBindingInterceptor(WebAsyncManager asyncManager, String key) {
CallableProcessingInterceptor cpi = asyncManager.getCallableInterceptor(key);
if (cpi == null) {
return false;
}
((AsyncRequestInterceptor) asyncManager.getCallableInterceptor(key)).bindSession();
((AsyncRequestInterceptor) cpi).bindEntityManager();
return true;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.LinkedList;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceContext;
@@ -327,10 +326,8 @@ public class PersistenceAnnotationBeanPostProcessor
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
if (beanType != null) {
InjectionMetadata metadata = findPersistenceMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
InjectionMetadata metadata = findPersistenceMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
@Override
@@ -459,7 +456,7 @@ public class PersistenceAnnotationBeanPostProcessor
* @see #setPersistenceUnits
*/
@Nullable
protected EntityManagerFactory getPersistenceUnit(String unitName) {
protected EntityManagerFactory getPersistenceUnit(@Nullable String unitName) {
if (this.persistenceUnits != null) {
String unitNameForLookup = (unitName != null ? unitName : "");
if ("".equals(unitNameForLookup)) {
@@ -491,7 +488,7 @@ public class PersistenceAnnotationBeanPostProcessor
* @see #setExtendedPersistenceContexts
*/
@Nullable
protected EntityManager getPersistenceContext(String unitName, boolean extended) {
protected EntityManager getPersistenceContext(@Nullable String unitName, boolean extended) {
Map<String, String> contexts = (extended ? this.extendedPersistenceContexts : this.persistenceContexts);
if (contexts != null) {
String unitNameForLookup = (unitName != null ? unitName : "");
@@ -523,7 +520,7 @@ public class PersistenceAnnotationBeanPostProcessor
* @return the EntityManagerFactory
* @throws NoSuchBeanDefinitionException if there is no such EntityManagerFactory in the context
*/
protected EntityManagerFactory findEntityManagerFactory(@Nullable String unitName, String requestingBeanName)
protected EntityManagerFactory findEntityManagerFactory(@Nullable String unitName, @Nullable String requestingBeanName)
throws NoSuchBeanDefinitionException {
if (this.beanFactory == null) {
@@ -549,11 +546,11 @@ public class PersistenceAnnotationBeanPostProcessor
* @return the EntityManagerFactory
* @throws NoSuchBeanDefinitionException if there is no such EntityManagerFactory in the context
*/
protected EntityManagerFactory findNamedEntityManagerFactory(String unitName, String requestingBeanName)
protected EntityManagerFactory findNamedEntityManagerFactory(String unitName, @Nullable String requestingBeanName)
throws NoSuchBeanDefinitionException {
EntityManagerFactory emf = EntityManagerFactoryUtils.findEntityManagerFactory(this.beanFactory, unitName);
if (this.beanFactory instanceof ConfigurableBeanFactory) {
if (requestingBeanName != null && this.beanFactory instanceof ConfigurableBeanFactory) {
((ConfigurableBeanFactory) this.beanFactory).registerDependentBean(unitName, requestingBeanName);
}
return emf;
@@ -564,14 +561,16 @@ public class PersistenceAnnotationBeanPostProcessor
* @return the default EntityManagerFactory
* @throws NoSuchBeanDefinitionException if there is no single EntityManagerFactory in the context
*/
protected EntityManagerFactory findDefaultEntityManagerFactory(String requestingBeanName)
protected EntityManagerFactory findDefaultEntityManagerFactory(@Nullable String requestingBeanName)
throws NoSuchBeanDefinitionException {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
// Fancy variant with dependency registration
ConfigurableListableBeanFactory clbf = (ConfigurableListableBeanFactory) this.beanFactory;
NamedBeanHolder<EntityManagerFactory> emfHolder = clbf.resolveNamedBean(EntityManagerFactory.class);
clbf.registerDependentBean(emfHolder.getBeanName(), requestingBeanName);
if (requestingBeanName != null) {
clbf.registerDependentBean(emfHolder.getBeanName(), requestingBeanName);
}
return emfHolder.getBeanInstance();
}
else {
@@ -665,7 +664,7 @@ public class PersistenceAnnotationBeanPostProcessor
* Resolve the object against the application context.
*/
@Override
protected Object getResourceToInject(Object target, String requestingBeanName) {
protected Object getResourceToInject(Object target, @Nullable String requestingBeanName) {
// Resolves to EntityManagerFactory or EntityManager.
if (this.type != null) {
return (this.type == PersistenceContextType.EXTENDED ?
@@ -678,7 +677,7 @@ public class PersistenceAnnotationBeanPostProcessor
}
}
private EntityManagerFactory resolveEntityManagerFactory(String requestingBeanName) {
private EntityManagerFactory resolveEntityManagerFactory(@Nullable String requestingBeanName) {
// Obtain EntityManagerFactory from JNDI?
EntityManagerFactory emf = getPersistenceUnit(this.unitName);
if (emf == null) {
@@ -688,7 +687,7 @@ public class PersistenceAnnotationBeanPostProcessor
return emf;
}
private EntityManager resolveEntityManager(String requestingBeanName) {
private EntityManager resolveEntityManager(@Nullable String requestingBeanName) {
// Obtain EntityManager reference from JNDI?
EntityManager em = getPersistenceContext(this.unitName, false);
if (em == null) {
@@ -716,7 +715,7 @@ public class PersistenceAnnotationBeanPostProcessor
return em;
}
private EntityManager resolveExtendedEntityManager(Object target, String requestingBeanName) {
private EntityManager resolveExtendedEntityManager(Object target, @Nullable String requestingBeanName) {
// Obtain EntityManager reference from JNDI?
EntityManager em = getPersistenceContext(this.unitName, true);
if (em == null) {
@@ -731,7 +730,7 @@ public class PersistenceAnnotationBeanPostProcessor
em = ExtendedEntityManagerCreator.createContainerManagedEntityManager(
emf, this.properties, this.synchronizedWithTransaction);
}
if (em instanceof EntityManagerProxy && beanFactory != null &&
if (em instanceof EntityManagerProxy && beanFactory != null && requestingBeanName != null &&
beanFactory.containsBean(requestingBeanName) && !beanFactory.isPrototype(requestingBeanName)) {
extendedEntityManagersToClose.put(target, ((EntityManagerProxy) em).getTargetEntityManager());
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2017 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.
@@ -20,6 +20,7 @@ import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import org.springframework.lang.Nullable;
import org.springframework.orm.jpa.JpaDialect;
import org.springframework.orm.jpa.JpaVendorAdapter;
@@ -53,6 +54,7 @@ public abstract class AbstractJpaVendorAdapter implements JpaVendorAdapter {
/**
* Return the target database to operate on.
*/
@Nullable
protected Database getDatabase() {
return this.database;
}
@@ -68,6 +70,7 @@ public abstract class AbstractJpaVendorAdapter implements JpaVendorAdapter {
/**
* Return the name of the target database to operate on.
*/
@Nullable
protected String getDatabasePlatform() {
return this.databasePlatform;
}

View File

@@ -181,6 +181,7 @@ public class HibernateJpaDialect extends DefaultJpaDialect {
@Nullable
protected FlushMode prepareFlushMode(Session session, boolean readOnly) throws PersistenceException {
FlushMode flushMode = (FlushMode) ReflectionUtils.invokeMethod(getFlushMode, session);
Assert.state(flushMode != null, "No FlushMode from Session");
if (readOnly) {
// We should suppress flushing for a read-only transaction.
if (!flushMode.equals(FlushMode.MANUAL)) {
@@ -201,7 +202,9 @@ public class HibernateJpaDialect extends DefaultJpaDialect {
@Override
public void cleanupTransaction(@Nullable Object transactionData) {
((SessionTransactionData) transactionData).resetSessionState();
if (transactionData instanceof SessionTransactionData) {
((SessionTransactionData) transactionData).resetSessionState();
}
}
@Override
@@ -325,8 +328,9 @@ public class HibernateJpaDialect extends DefaultJpaDialect {
private final Integer previousIsolationLevel;
public SessionTransactionData(
Session session, FlushMode previousFlushMode, @Nullable Connection preparedCon, @Nullable Integer previousIsolationLevel) {
public SessionTransactionData(Session session, @Nullable FlushMode previousFlushMode,
@Nullable Connection preparedCon, @Nullable Integer previousIsolationLevel) {
this.session = session;
this.previousFlushMode = previousFlushMode;
this.preparedCon = preparedCon;
@@ -377,7 +381,9 @@ public class HibernateJpaDialect extends DefaultJpaDialect {
// Reflective lookup to find SessionImpl's connection() method on Hibernate 4.x/5.x
connectionMethodToUse = session.getClass().getMethod("connection");
}
return (Connection) ReflectionUtils.invokeMethod(connectionMethodToUse, session);
Connection con = (Connection) ReflectionUtils.invokeMethod(connectionMethodToUse, session);
Assert.state(con != null, "No Connection from Session");
return con;
}
catch (NoSuchMethodException ex) {
throw new IllegalStateException("Cannot find connection() method on Hibernate Session", ex);