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:
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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...
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user