@Nullable all the way: null-safety at field level
This commits extends nullability declarations to the field level, formalizing the interaction between methods and their underlying fields and therefore avoiding any nullability mismatch. Issue: SPR-15720
This commit is contained in:
@@ -29,8 +29,10 @@ import org.springframework.lang.Nullable;
|
||||
@SuppressWarnings("serial")
|
||||
public class ObjectOptimisticLockingFailureException extends OptimisticLockingFailureException {
|
||||
|
||||
@Nullable
|
||||
private Object persistentClass;
|
||||
|
||||
@Nullable
|
||||
private Object identifier;
|
||||
|
||||
|
||||
@@ -151,6 +153,7 @@ public class ObjectOptimisticLockingFailureException extends OptimisticLockingFa
|
||||
/**
|
||||
* Return the identifier of the object for which the locking failed.
|
||||
*/
|
||||
@Nullable
|
||||
public Object getIdentifier() {
|
||||
return this.identifier;
|
||||
}
|
||||
|
||||
@@ -29,8 +29,10 @@ import org.springframework.lang.Nullable;
|
||||
@SuppressWarnings("serial")
|
||||
public class ObjectRetrievalFailureException extends DataRetrievalFailureException {
|
||||
|
||||
@Nullable
|
||||
private Object persistentClass;
|
||||
|
||||
@Nullable
|
||||
private Object identifier;
|
||||
|
||||
|
||||
@@ -125,6 +127,7 @@ public class ObjectRetrievalFailureException extends DataRetrievalFailureExcepti
|
||||
/**
|
||||
* Return the identifier of the object that was not found.
|
||||
*/
|
||||
@Nullable
|
||||
public Object getIdentifier() {
|
||||
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.
|
||||
@@ -45,6 +45,7 @@ class ConfigurableJtaPlatform implements JtaPlatform {
|
||||
|
||||
private final UserTransaction userTransaction;
|
||||
|
||||
@Nullable
|
||||
private final TransactionSynchronizationRegistry transactionSynchronizationRegistry;
|
||||
|
||||
|
||||
@@ -55,7 +56,9 @@ class ConfigurableJtaPlatform implements JtaPlatform {
|
||||
* @param ut the JTA UserTransaction reference (optional)
|
||||
* @param tsr the JTA 1.1 TransactionSynchronizationRegistry (optional)
|
||||
*/
|
||||
public ConfigurableJtaPlatform(TransactionManager tm, @Nullable UserTransaction ut, @Nullable TransactionSynchronizationRegistry tsr) {
|
||||
public ConfigurableJtaPlatform(TransactionManager tm, @Nullable UserTransaction ut,
|
||||
@Nullable TransactionSynchronizationRegistry tsr) {
|
||||
|
||||
Assert.notNull(tm, "TransactionManager reference must not be null");
|
||||
this.transactionManager = tm;
|
||||
this.userTransaction = (ut != null ? ut : new UserTransactionAdapter(tm));
|
||||
|
||||
@@ -110,8 +110,10 @@ import org.springframework.util.Assert;
|
||||
public class HibernateTransactionManager extends AbstractPlatformTransactionManager
|
||||
implements ResourceTransactionManager, BeanFactoryAware, InitializingBean {
|
||||
|
||||
@Nullable
|
||||
private SessionFactory sessionFactory;
|
||||
|
||||
@Nullable
|
||||
private DataSource dataSource;
|
||||
|
||||
private boolean autodetectDataSource = true;
|
||||
@@ -122,12 +124,14 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
|
||||
|
||||
private boolean hibernateManagedSession = false;
|
||||
|
||||
@Nullable
|
||||
private Object entityInterceptor;
|
||||
|
||||
/**
|
||||
* Just needed for entityInterceptorBeanName.
|
||||
* @see #setEntityInterceptorBeanName
|
||||
*/
|
||||
@Nullable
|
||||
private BeanFactory beanFactory;
|
||||
|
||||
|
||||
@@ -788,12 +792,14 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
|
||||
*/
|
||||
private class HibernateTransactionObject extends JdbcTransactionObjectSupport {
|
||||
|
||||
@Nullable
|
||||
private SessionHolder sessionHolder;
|
||||
|
||||
private boolean newSessionHolder;
|
||||
|
||||
private boolean newSession;
|
||||
|
||||
@Nullable
|
||||
private Integer previousHoldability;
|
||||
|
||||
public void setSession(Session session) {
|
||||
@@ -850,7 +856,7 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
|
||||
}
|
||||
|
||||
public void setRollbackOnly() {
|
||||
this.sessionHolder.setRollbackOnly();
|
||||
getSessionHolder().setRollbackOnly();
|
||||
if (hasConnectionHolder()) {
|
||||
getConnectionHolder().setRollbackOnly();
|
||||
}
|
||||
@@ -858,14 +864,14 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
|
||||
|
||||
@Override
|
||||
public boolean isRollbackOnly() {
|
||||
return this.sessionHolder.isRollbackOnly() ||
|
||||
return getSessionHolder().isRollbackOnly() ||
|
||||
(hasConnectionHolder() && getConnectionHolder().isRollbackOnly());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
try {
|
||||
this.sessionHolder.getSession().flush();
|
||||
getSessionHolder().getSession().flush();
|
||||
}
|
||||
catch (HibernateException ex) {
|
||||
throw convertHibernateAccessException(ex);
|
||||
@@ -888,6 +894,7 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
|
||||
|
||||
private final SessionHolder sessionHolder;
|
||||
|
||||
@Nullable
|
||||
private final ConnectionHolder connectionHolder;
|
||||
|
||||
private SuspendedResourcesHolder(SessionHolder sessionHolder, @Nullable ConnectionHolder conHolder) {
|
||||
|
||||
@@ -63,52 +63,75 @@ import org.springframework.util.Assert;
|
||||
public class LocalSessionFactoryBean extends HibernateExceptionTranslator
|
||||
implements FactoryBean<SessionFactory>, ResourceLoaderAware, InitializingBean, DisposableBean {
|
||||
|
||||
@Nullable
|
||||
private DataSource dataSource;
|
||||
|
||||
@Nullable
|
||||
private Resource[] configLocations;
|
||||
|
||||
@Nullable
|
||||
private String[] mappingResources;
|
||||
|
||||
@Nullable
|
||||
private Resource[] mappingLocations;
|
||||
|
||||
@Nullable
|
||||
private Resource[] cacheableMappingLocations;
|
||||
|
||||
@Nullable
|
||||
private Resource[] mappingJarLocations;
|
||||
|
||||
@Nullable
|
||||
private Resource[] mappingDirectoryLocations;
|
||||
|
||||
@Nullable
|
||||
private Interceptor entityInterceptor;
|
||||
|
||||
@Nullable
|
||||
private ImplicitNamingStrategy implicitNamingStrategy;
|
||||
|
||||
@Nullable
|
||||
private PhysicalNamingStrategy physicalNamingStrategy;
|
||||
|
||||
@Nullable
|
||||
private Object jtaTransactionManager;
|
||||
|
||||
@Nullable
|
||||
private MultiTenantConnectionProvider multiTenantConnectionProvider;
|
||||
|
||||
@Nullable
|
||||
private CurrentTenantIdentifierResolver currentTenantIdentifierResolver;
|
||||
|
||||
@Nullable
|
||||
private TypeFilter[] entityTypeFilters;
|
||||
|
||||
@Nullable
|
||||
private Properties hibernateProperties;
|
||||
|
||||
@Nullable
|
||||
private Class<?>[] annotatedClasses;
|
||||
|
||||
@Nullable
|
||||
private String[] annotatedPackages;
|
||||
|
||||
@Nullable
|
||||
private String[] packagesToScan;
|
||||
|
||||
@Nullable
|
||||
private AsyncTaskExecutor bootstrapExecutor;
|
||||
|
||||
private boolean metadataSourcesAccessed = false;
|
||||
|
||||
@Nullable
|
||||
private MetadataSources metadataSources;
|
||||
|
||||
@Nullable
|
||||
private ResourcePatternResolver resourcePatternResolver;
|
||||
|
||||
@Nullable
|
||||
private Configuration configuration;
|
||||
|
||||
@Nullable
|
||||
private SessionFactory sessionFactory;
|
||||
|
||||
|
||||
@@ -372,7 +395,7 @@ public class LocalSessionFactoryBean extends HibernateExceptionTranslator
|
||||
* @param resourceLoader the ResourceLoader to use (never {@code null})
|
||||
*/
|
||||
@Override
|
||||
public void setResourceLoader(@Nullable ResourceLoader resourceLoader) {
|
||||
public void setResourceLoader(ResourceLoader resourceLoader) {
|
||||
this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
|
||||
}
|
||||
|
||||
@@ -409,7 +432,7 @@ public class LocalSessionFactoryBean extends HibernateExceptionTranslator
|
||||
if (this.mappingResources != null) {
|
||||
// Register given Hibernate mapping definitions, contained in resource files.
|
||||
for (String mapping : this.mappingResources) {
|
||||
Resource mr = new ClassPathResource(mapping.trim(), this.resourcePatternResolver.getClassLoader());
|
||||
Resource mr = new ClassPathResource(mapping.trim(), getResourceLoader().getClassLoader());
|
||||
sfb.addInputStream(mr.getInputStream());
|
||||
}
|
||||
}
|
||||
@@ -543,7 +566,9 @@ public class LocalSessionFactoryBean extends HibernateExceptionTranslator
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
this.sessionFactory.close();
|
||||
if (this.sessionFactory != null) {
|
||||
this.sessionFactory.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -94,6 +94,7 @@ public class LocalSessionFactoryBuilder extends Configuration {
|
||||
|
||||
private final ResourcePatternResolver resourcePatternResolver;
|
||||
|
||||
@Nullable
|
||||
private TypeFilter[] entityTypeFilters = DEFAULT_ENTITY_TYPE_FILTERS;
|
||||
|
||||
|
||||
|
||||
@@ -40,8 +40,10 @@ public class SessionHolder extends ResourceHolderSupport {
|
||||
|
||||
private final Session session;
|
||||
|
||||
@Nullable
|
||||
private Transaction transaction;
|
||||
|
||||
@Nullable
|
||||
private FlushMode previousFlushMode;
|
||||
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.hibernate.context.spi.CurrentSessionContext;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
/**
|
||||
@@ -47,8 +48,10 @@ public class SpringSessionContext implements CurrentSessionContext {
|
||||
|
||||
private final SessionFactoryImplementor sessionFactory;
|
||||
|
||||
@Nullable
|
||||
private TransactionManager transactionManager;
|
||||
|
||||
@Nullable
|
||||
private CurrentSessionContext jtaSessionContext;
|
||||
|
||||
|
||||
@@ -102,7 +105,7 @@ public class SpringSessionContext implements CurrentSessionContext {
|
||||
return session;
|
||||
}
|
||||
|
||||
if (this.transactionManager != null) {
|
||||
if (this.transactionManager != null && this.jtaSessionContext != null) {
|
||||
try {
|
||||
if (this.transactionManager.getStatus() == Status.STATUS_ACTIVE) {
|
||||
Session session = this.jtaSessionContext.currentSession();
|
||||
|
||||
@@ -55,6 +55,7 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public abstract class HibernateDaoSupport extends DaoSupport {
|
||||
|
||||
@Nullable
|
||||
private HibernateTemplate hibernateTemplate;
|
||||
|
||||
|
||||
@@ -110,6 +111,7 @@ public abstract class HibernateDaoSupport extends DaoSupport {
|
||||
* {@code new HibernateTemplate(getSessionFactory())}, in which case
|
||||
* you're allowed to customize the settings on the resulting instance.
|
||||
*/
|
||||
@Nullable
|
||||
public final HibernateTemplate getHibernateTemplate() {
|
||||
return this.hibernateTemplate;
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@ 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;
|
||||
|
||||
@@ -92,35 +93,47 @@ public abstract class AbstractEntityManagerFactoryBean implements
|
||||
/** Logger available to subclasses */
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
@Nullable
|
||||
private PersistenceProvider persistenceProvider;
|
||||
|
||||
@Nullable
|
||||
private String persistenceUnitName;
|
||||
|
||||
private final Map<String, Object> jpaPropertyMap = new HashMap<>();
|
||||
|
||||
@Nullable
|
||||
private Class<? extends EntityManagerFactory> entityManagerFactoryInterface;
|
||||
|
||||
@Nullable
|
||||
private Class<? extends EntityManager> entityManagerInterface;
|
||||
|
||||
@Nullable
|
||||
private JpaDialect jpaDialect;
|
||||
|
||||
@Nullable
|
||||
private JpaVendorAdapter jpaVendorAdapter;
|
||||
|
||||
@Nullable
|
||||
private AsyncTaskExecutor bootstrapExecutor;
|
||||
|
||||
private ClassLoader beanClassLoader = getClass().getClassLoader();
|
||||
|
||||
@Nullable
|
||||
private BeanFactory beanFactory;
|
||||
|
||||
@Nullable
|
||||
private String beanName;
|
||||
|
||||
/** Raw EntityManagerFactory as returned by the PersistenceProvider */
|
||||
@Nullable
|
||||
private EntityManagerFactory nativeEntityManagerFactory;
|
||||
|
||||
/** Future for lazily initializing raw target EntityManagerFactory */
|
||||
@Nullable
|
||||
private Future<EntityManagerFactory> nativeEntityManagerFactoryFuture;
|
||||
|
||||
/** Exposed client-level EntityManagerFactory proxy */
|
||||
@Nullable
|
||||
private EntityManagerFactory entityManagerFactory;
|
||||
|
||||
|
||||
@@ -489,6 +502,7 @@ public abstract class AbstractEntityManagerFactoryBean implements
|
||||
return this.nativeEntityManagerFactory;
|
||||
}
|
||||
else {
|
||||
Assert.state(this.nativeEntityManagerFactoryFuture != null, "No native EntityManagerFactory available");
|
||||
try {
|
||||
return this.nativeEntityManagerFactoryFuture.get();
|
||||
}
|
||||
@@ -538,10 +552,12 @@ public abstract class AbstractEntityManagerFactoryBean implements
|
||||
*/
|
||||
@Override
|
||||
public void destroy() {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Closing JPA EntityManagerFactory for persistence unit '" + getPersistenceUnitName() + "'");
|
||||
if (this.entityManagerFactory != null) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Closing JPA EntityManagerFactory for persistence unit '" + getPersistenceUnitName() + "'");
|
||||
}
|
||||
this.entityManagerFactory.close();
|
||||
}
|
||||
this.entityManagerFactory.close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -317,7 +317,7 @@ public abstract class EntityManagerFactoryUtils {
|
||||
* @param emf the EntityManagerFactory that the EntityManager has been created with
|
||||
* @see JpaDialect#cleanupTransaction
|
||||
*/
|
||||
private static void cleanupTransaction(Object transactionData, EntityManagerFactory emf) {
|
||||
private static void cleanupTransaction(@Nullable Object transactionData, EntityManagerFactory emf) {
|
||||
if (emf instanceof EntityManagerFactoryInfo) {
|
||||
EntityManagerFactoryInfo emfInfo = (EntityManagerFactoryInfo) emf;
|
||||
JpaDialect jpaDialect = emfInfo.getJpaDialect();
|
||||
@@ -443,8 +443,10 @@ public abstract class EntityManagerFactoryUtils {
|
||||
extends ResourceHolderSynchronization<EntityManagerHolder, EntityManagerFactory>
|
||||
implements Ordered {
|
||||
|
||||
@Nullable
|
||||
private final Object transactionData;
|
||||
|
||||
@Nullable
|
||||
private final JpaDialect jpaDialect;
|
||||
|
||||
private final boolean newEntityManager;
|
||||
|
||||
@@ -41,6 +41,7 @@ public class EntityManagerHolder extends ResourceHolderSupport {
|
||||
|
||||
private boolean transactionActive;
|
||||
|
||||
@Nullable
|
||||
private SavepointManager savepointManager;
|
||||
|
||||
|
||||
|
||||
@@ -248,6 +248,7 @@ public abstract class ExtendedEntityManagerCreator {
|
||||
|
||||
private final EntityManager target;
|
||||
|
||||
@Nullable
|
||||
private final PersistenceExceptionTranslator exceptionTranslator;
|
||||
|
||||
private final boolean jta;
|
||||
@@ -423,12 +424,14 @@ public abstract class ExtendedEntityManagerCreator {
|
||||
|
||||
private final EntityManager entityManager;
|
||||
|
||||
@Nullable
|
||||
private final PersistenceExceptionTranslator exceptionTranslator;
|
||||
|
||||
public volatile boolean closeOnCompletion = false;
|
||||
|
||||
public ExtendedEntityManagerSynchronization(
|
||||
EntityManager em, PersistenceExceptionTranslator exceptionTranslator) {
|
||||
EntityManager em, @Nullable PersistenceExceptionTranslator exceptionTranslator) {
|
||||
|
||||
super(new EntityManagerHolder(em), em);
|
||||
this.entityManager = em;
|
||||
this.exceptionTranslator = exceptionTranslator;
|
||||
|
||||
@@ -113,12 +113,15 @@ import org.springframework.util.CollectionUtils;
|
||||
public class JpaTransactionManager extends AbstractPlatformTransactionManager
|
||||
implements ResourceTransactionManager, BeanFactoryAware, InitializingBean {
|
||||
|
||||
@Nullable
|
||||
private EntityManagerFactory entityManagerFactory;
|
||||
|
||||
@Nullable
|
||||
private String persistenceUnitName;
|
||||
|
||||
private final Map<String, Object> jpaPropertyMap = new HashMap<>();
|
||||
|
||||
@Nullable
|
||||
private DataSource dataSource;
|
||||
|
||||
private JpaDialect jpaDialect = new DefaultJpaDialect();
|
||||
@@ -630,19 +633,23 @@ public class JpaTransactionManager extends AbstractPlatformTransactionManager
|
||||
*/
|
||||
private class JpaTransactionObject extends JdbcTransactionObjectSupport {
|
||||
|
||||
@Nullable
|
||||
private EntityManagerHolder entityManagerHolder;
|
||||
|
||||
private boolean newEntityManagerHolder;
|
||||
|
||||
@Nullable
|
||||
private Object transactionData;
|
||||
|
||||
public void setEntityManagerHolder(
|
||||
@Nullable EntityManagerHolder entityManagerHolder, boolean newEntityManagerHolder) {
|
||||
|
||||
this.entityManagerHolder = entityManagerHolder;
|
||||
this.newEntityManagerHolder = newEntityManagerHolder;
|
||||
}
|
||||
|
||||
public EntityManagerHolder getEntityManagerHolder() {
|
||||
Assert.state(this.entityManagerHolder != null, "No EntityManagerHolder available");
|
||||
return this.entityManagerHolder;
|
||||
}
|
||||
|
||||
@@ -660,18 +667,19 @@ public class JpaTransactionManager extends AbstractPlatformTransactionManager
|
||||
|
||||
public void setTransactionData(@Nullable Object transactionData) {
|
||||
this.transactionData = transactionData;
|
||||
this.entityManagerHolder.setTransactionActive(true);
|
||||
getEntityManagerHolder().setTransactionActive(true);
|
||||
if (transactionData instanceof SavepointManager) {
|
||||
this.entityManagerHolder.setSavepointManager((SavepointManager) transactionData);
|
||||
getEntityManagerHolder().setSavepointManager((SavepointManager) transactionData);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Object getTransactionData() {
|
||||
return this.transactionData;
|
||||
}
|
||||
|
||||
public void setRollbackOnly() {
|
||||
EntityTransaction tx = this.entityManagerHolder.getEntityManager().getTransaction();
|
||||
EntityTransaction tx = getEntityManagerHolder().getEntityManager().getTransaction();
|
||||
if (tx.isActive()) {
|
||||
tx.setRollbackOnly();
|
||||
}
|
||||
@@ -682,14 +690,14 @@ public class JpaTransactionManager extends AbstractPlatformTransactionManager
|
||||
|
||||
@Override
|
||||
public boolean isRollbackOnly() {
|
||||
EntityTransaction tx = this.entityManagerHolder.getEntityManager().getTransaction();
|
||||
EntityTransaction tx = getEntityManagerHolder().getEntityManager().getTransaction();
|
||||
return tx.getRollbackOnly();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
try {
|
||||
this.entityManagerHolder.getEntityManager().flush();
|
||||
getEntityManagerHolder().getEntityManager().flush();
|
||||
}
|
||||
catch (RuntimeException ex) {
|
||||
throw DataAccessUtils.translateIfNecessary(ex, getJpaDialect());
|
||||
@@ -698,7 +706,7 @@ public class JpaTransactionManager extends AbstractPlatformTransactionManager
|
||||
|
||||
@Override
|
||||
public Object createSavepoint() throws TransactionException {
|
||||
if (this.entityManagerHolder.isRollbackOnly()) {
|
||||
if (getEntityManagerHolder().isRollbackOnly()) {
|
||||
throw new CannotCreateTransactionException(
|
||||
"Cannot create savepoint for transaction which is already marked as rollback-only");
|
||||
}
|
||||
@@ -708,7 +716,7 @@ public class JpaTransactionManager extends AbstractPlatformTransactionManager
|
||||
@Override
|
||||
public void rollbackToSavepoint(Object savepoint) throws TransactionException {
|
||||
getSavepointManager().rollbackToSavepoint(savepoint);
|
||||
this.entityManagerHolder.resetRollbackOnly();
|
||||
getEntityManagerHolder().resetRollbackOnly();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -739,6 +747,7 @@ public class JpaTransactionManager extends AbstractPlatformTransactionManager
|
||||
|
||||
private final EntityManagerHolder entityManagerHolder;
|
||||
|
||||
@Nullable
|
||||
private final ConnectionHolder connectionHolder;
|
||||
|
||||
private SuspendedResourcesHolder(EntityManagerHolder emHolder, @Nullable ConnectionHolder conHolder) {
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.springframework.context.weaving.LoadTimeWeaverAware;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.instrument.classloading.LoadTimeWeaver;
|
||||
import org.springframework.jdbc.datasource.lookup.SingleDataSourceLookup;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager;
|
||||
import org.springframework.orm.jpa.persistenceunit.PersistenceUnitManager;
|
||||
import org.springframework.orm.jpa.persistenceunit.PersistenceUnitPostProcessor;
|
||||
@@ -88,11 +89,13 @@ import org.springframework.util.ClassUtils;
|
||||
public class LocalContainerEntityManagerFactoryBean extends AbstractEntityManagerFactoryBean
|
||||
implements ResourceLoaderAware, LoadTimeWeaverAware {
|
||||
|
||||
@Nullable
|
||||
private PersistenceUnitManager persistenceUnitManager;
|
||||
|
||||
private final DefaultPersistenceUnitManager internalPersistenceUnitManager =
|
||||
new DefaultPersistenceUnitManager();
|
||||
|
||||
@Nullable
|
||||
private PersistenceUnitInfo persistenceUnitInfo;
|
||||
|
||||
|
||||
|
||||
@@ -179,10 +179,12 @@ public abstract class SharedEntityManagerCreator {
|
||||
|
||||
private final EntityManagerFactory targetFactory;
|
||||
|
||||
@Nullable
|
||||
private final Map<?, ?> properties;
|
||||
|
||||
private final boolean synchronizedWithTransaction;
|
||||
|
||||
@Nullable
|
||||
private transient volatile ClassLoader proxyClassLoader;
|
||||
|
||||
public SharedEntityManagerInvocationHandler(
|
||||
@@ -341,6 +343,7 @@ public abstract class SharedEntityManagerCreator {
|
||||
|
||||
private final Query target;
|
||||
|
||||
@Nullable
|
||||
private EntityManager em;
|
||||
|
||||
public DeferredQueryInvocationHandler(Query target, EntityManager em) {
|
||||
|
||||
@@ -127,30 +127,41 @@ public class DefaultPersistenceUnitManager
|
||||
|
||||
private String[] persistenceXmlLocations = new String[] {DEFAULT_PERSISTENCE_XML_LOCATION};
|
||||
|
||||
@Nullable
|
||||
private String defaultPersistenceUnitRootLocation = ORIGINAL_DEFAULT_PERSISTENCE_UNIT_ROOT_LOCATION;
|
||||
|
||||
@Nullable
|
||||
private String defaultPersistenceUnitName = ORIGINAL_DEFAULT_PERSISTENCE_UNIT_NAME;
|
||||
|
||||
@Nullable
|
||||
private String[] packagesToScan;
|
||||
|
||||
@Nullable
|
||||
private String[] mappingResources;
|
||||
|
||||
@Nullable
|
||||
private SharedCacheMode sharedCacheMode;
|
||||
|
||||
@Nullable
|
||||
private ValidationMode validationMode;
|
||||
|
||||
private DataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
|
||||
|
||||
@Nullable
|
||||
private DataSource defaultDataSource;
|
||||
|
||||
@Nullable
|
||||
private DataSource defaultJtaDataSource;
|
||||
|
||||
@Nullable
|
||||
private PersistenceUnitPostProcessor[] persistenceUnitPostProcessors;
|
||||
|
||||
@Nullable
|
||||
private LoadTimeWeaver loadTimeWeaver;
|
||||
|
||||
private ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
|
||||
|
||||
@Nullable
|
||||
private CandidateComponentsIndex componentsIndex;
|
||||
|
||||
private final Set<String> persistenceUnitInfoNames = new HashSet<>();
|
||||
@@ -447,10 +458,10 @@ public class DefaultPersistenceUnitManager
|
||||
if (pui.getPersistenceUnitRootUrl() == null) {
|
||||
pui.setPersistenceUnitRootUrl(determineDefaultPersistenceUnitRootUrl());
|
||||
}
|
||||
if (pui.getJtaDataSource() == null) {
|
||||
if (pui.getJtaDataSource() == null && this.defaultJtaDataSource != null) {
|
||||
pui.setJtaDataSource(this.defaultJtaDataSource);
|
||||
}
|
||||
if (pui.getNonJtaDataSource() == null) {
|
||||
if (pui.getNonJtaDataSource() == null && this.defaultDataSource != null) {
|
||||
pui.setNonJtaDataSource(this.defaultDataSource);
|
||||
}
|
||||
if (this.sharedCacheMode != null) {
|
||||
@@ -517,17 +528,14 @@ public class DefaultPersistenceUnitManager
|
||||
*/
|
||||
private SpringPersistenceUnitInfo buildDefaultPersistenceUnitInfo() {
|
||||
SpringPersistenceUnitInfo scannedUnit = new SpringPersistenceUnitInfo();
|
||||
scannedUnit.setPersistenceUnitName(this.defaultPersistenceUnitName);
|
||||
if (this.defaultPersistenceUnitName != null) {
|
||||
scannedUnit.setPersistenceUnitName(this.defaultPersistenceUnitName);
|
||||
}
|
||||
scannedUnit.setExcludeUnlistedClasses(true);
|
||||
|
||||
if (this.packagesToScan != null) {
|
||||
for (String pkg : this.packagesToScan) {
|
||||
if (this.componentsIndex != null) {
|
||||
addPackageFromIndex(scannedUnit, pkg);
|
||||
}
|
||||
else {
|
||||
scanPackage(scannedUnit, pkg);
|
||||
}
|
||||
scanPackage(scannedUnit, pkg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -555,18 +563,18 @@ public class DefaultPersistenceUnitManager
|
||||
return scannedUnit;
|
||||
}
|
||||
|
||||
private void addPackageFromIndex(SpringPersistenceUnitInfo scannedUnit, String pkg) {
|
||||
Set<String> candidates = new HashSet<>();
|
||||
for (AnnotationTypeFilter filter : entityTypeFilters) {
|
||||
candidates.addAll(this.componentsIndex
|
||||
.getCandidateTypes(pkg, filter.getAnnotationType().getName()));
|
||||
}
|
||||
candidates.forEach(scannedUnit::addManagedClassName);
|
||||
Set<String> managedPackages = this.componentsIndex.getCandidateTypes(pkg, "package-info");
|
||||
managedPackages.forEach(scannedUnit::addManagedPackage);
|
||||
}
|
||||
|
||||
private void scanPackage(SpringPersistenceUnitInfo scannedUnit, String pkg) {
|
||||
if (this.componentsIndex != null) {
|
||||
Set<String> candidates = new HashSet<>();
|
||||
for (AnnotationTypeFilter filter : entityTypeFilters) {
|
||||
candidates.addAll(this.componentsIndex.getCandidateTypes(pkg, filter.getAnnotationType().getName()));
|
||||
}
|
||||
candidates.forEach(scannedUnit::addManagedClassName);
|
||||
Set<String> managedPackages = this.componentsIndex.getCandidateTypes(pkg, "package-info");
|
||||
managedPackages.forEach(scannedUnit::addManagedPackage);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
|
||||
ClassUtils.convertClassNameToResourcePath(pkg) + CLASS_RESOURCE_PATTERN;
|
||||
@@ -709,7 +717,7 @@ public class DefaultPersistenceUnitManager
|
||||
throw new IllegalStateException("All persistence units from " +
|
||||
ObjectUtils.nullSafeToString(this.persistenceXmlLocations) + " already obtained");
|
||||
}
|
||||
if (this.persistenceUnitInfos.size() > 1) {
|
||||
if (this.persistenceUnitInfos.size() > 1 && this.defaultPersistenceUnitName != null) {
|
||||
return obtainPersistenceUnitInfo(this.defaultPersistenceUnitName);
|
||||
}
|
||||
PersistenceUnitInfo pui = this.persistenceUnitInfos.values().iterator().next();
|
||||
|
||||
@@ -27,6 +27,7 @@ import javax.persistence.spi.PersistenceUnitTransactionType;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
@@ -44,20 +45,26 @@ import org.springframework.util.ClassUtils;
|
||||
*/
|
||||
public class MutablePersistenceUnitInfo implements SmartPersistenceUnitInfo {
|
||||
|
||||
@Nullable
|
||||
private String persistenceUnitName;
|
||||
|
||||
@Nullable
|
||||
private String persistenceProviderClassName;
|
||||
|
||||
@Nullable
|
||||
private PersistenceUnitTransactionType transactionType;
|
||||
|
||||
@Nullable
|
||||
private DataSource nonJtaDataSource;
|
||||
|
||||
@Nullable
|
||||
private DataSource jtaDataSource;
|
||||
|
||||
private final List<String> mappingFileNames = new LinkedList<>();
|
||||
|
||||
private List<URL> jarFileUrls = new LinkedList<>();
|
||||
|
||||
@Nullable
|
||||
private URL persistenceUnitRootUrl;
|
||||
|
||||
private final List<String> managedClassNames = new LinkedList<>();
|
||||
@@ -74,6 +81,7 @@ public class MutablePersistenceUnitInfo implements SmartPersistenceUnitInfo {
|
||||
|
||||
private String persistenceXMLSchemaVersion = "2.0";
|
||||
|
||||
@Nullable
|
||||
private String persistenceProviderPackageName;
|
||||
|
||||
|
||||
@@ -82,6 +90,7 @@ public class MutablePersistenceUnitInfo implements SmartPersistenceUnitInfo {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getPersistenceUnitName() {
|
||||
return this.persistenceUnitName;
|
||||
}
|
||||
@@ -91,6 +100,7 @@ public class MutablePersistenceUnitInfo implements SmartPersistenceUnitInfo {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getPersistenceProviderClassName() {
|
||||
return this.persistenceProviderClassName;
|
||||
}
|
||||
@@ -218,13 +228,11 @@ public class MutablePersistenceUnitInfo implements SmartPersistenceUnitInfo {
|
||||
}
|
||||
|
||||
public void addProperty(String name, String value) {
|
||||
if (this.properties == null) {
|
||||
this.properties = new Properties();
|
||||
}
|
||||
this.properties.setProperty(name, value);
|
||||
}
|
||||
|
||||
public void setProperties(Properties properties) {
|
||||
Assert.notNull(properties, "Properties must not be null");
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,8 +38,10 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
class SpringPersistenceUnitInfo extends MutablePersistenceUnitInfo {
|
||||
|
||||
@Nullable
|
||||
private LoadTimeWeaver loadTimeWeaver;
|
||||
|
||||
@Nullable
|
||||
private 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.
|
||||
@@ -74,10 +74,13 @@ public class OpenEntityManagerInViewFilter extends OncePerRequestFilter {
|
||||
public static final String DEFAULT_ENTITY_MANAGER_FACTORY_BEAN_NAME = "entityManagerFactory";
|
||||
|
||||
|
||||
@Nullable
|
||||
private String entityManagerFactoryBeanName;
|
||||
|
||||
@Nullable
|
||||
private String persistenceUnitName;
|
||||
|
||||
@Nullable
|
||||
private volatile EntityManagerFactory entityManagerFactory;
|
||||
|
||||
|
||||
@@ -97,6 +100,7 @@ public class OpenEntityManagerInViewFilter extends OncePerRequestFilter {
|
||||
* Return the bean name of the EntityManagerFactory to fetch from Spring's
|
||||
* root application context.
|
||||
*/
|
||||
@Nullable
|
||||
protected String getEntityManagerFactoryBeanName() {
|
||||
return this.entityManagerFactoryBeanName;
|
||||
}
|
||||
@@ -202,10 +206,12 @@ public class OpenEntityManagerInViewFilter extends OncePerRequestFilter {
|
||||
* @see #lookupEntityManagerFactory()
|
||||
*/
|
||||
protected EntityManagerFactory lookupEntityManagerFactory(HttpServletRequest request) {
|
||||
if (this.entityManagerFactory == null) {
|
||||
this.entityManagerFactory = lookupEntityManagerFactory();
|
||||
EntityManagerFactory emf = this.entityManagerFactory;
|
||||
if (emf == null) {
|
||||
emf = lookupEntityManagerFactory();
|
||||
this.entityManagerFactory = emf;
|
||||
}
|
||||
return this.entityManagerFactory;
|
||||
return emf;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -61,6 +61,7 @@ import org.springframework.orm.jpa.EntityManagerFactoryUtils;
|
||||
import org.springframework.orm.jpa.EntityManagerProxy;
|
||||
import org.springframework.orm.jpa.ExtendedEntityManagerCreator;
|
||||
import org.springframework.orm.jpa.SharedEntityManagerCreator;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
@@ -169,27 +170,30 @@ public class PersistenceAnnotationBeanPostProcessor
|
||||
implements InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor,
|
||||
MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware, Serializable {
|
||||
|
||||
@Nullable
|
||||
private Object jndiEnvironment;
|
||||
|
||||
private boolean resourceRef = true;
|
||||
|
||||
@Nullable
|
||||
private transient Map<String, String> persistenceUnits;
|
||||
|
||||
@Nullable
|
||||
private transient Map<String, String> persistenceContexts;
|
||||
|
||||
@Nullable
|
||||
private transient Map<String, String> extendedPersistenceContexts;
|
||||
|
||||
private transient String defaultPersistenceUnitName = "";
|
||||
|
||||
private int order = Ordered.LOWEST_PRECEDENCE - 4;
|
||||
|
||||
@Nullable
|
||||
private transient ListableBeanFactory beanFactory;
|
||||
|
||||
private transient final Map<String, InjectionMetadata> injectionMetadataCache =
|
||||
new ConcurrentHashMap<>(256);
|
||||
private transient final Map<String, InjectionMetadata> injectionMetadataCache = new ConcurrentHashMap<>(256);
|
||||
|
||||
private final Map<Object, EntityManager> extendedEntityManagersToClose =
|
||||
new ConcurrentHashMap<>(16);
|
||||
private final Map<Object, EntityManager> extendedEntityManagersToClose = new ConcurrentHashMap<>(16);
|
||||
|
||||
|
||||
/**
|
||||
@@ -516,9 +520,6 @@ public class PersistenceAnnotationBeanPostProcessor
|
||||
protected EntityManagerFactory findEntityManagerFactory(@Nullable String unitName, @Nullable String requestingBeanName)
|
||||
throws NoSuchBeanDefinitionException {
|
||||
|
||||
if (this.beanFactory == null) {
|
||||
throw new IllegalStateException("ListableBeanFactory required for EntityManagerFactory bean lookup");
|
||||
}
|
||||
String unitNameForLookup = (unitName != null ? unitName : "");
|
||||
if ("".equals(unitNameForLookup)) {
|
||||
unitNameForLookup = this.defaultPersistenceUnitName;
|
||||
@@ -542,6 +543,8 @@ public class PersistenceAnnotationBeanPostProcessor
|
||||
protected EntityManagerFactory findNamedEntityManagerFactory(String unitName, @Nullable String requestingBeanName)
|
||||
throws NoSuchBeanDefinitionException {
|
||||
|
||||
Assert.state(this.beanFactory != null, "ListableBeanFactory required for EntityManagerFactory bean lookup");
|
||||
|
||||
EntityManagerFactory emf = EntityManagerFactoryUtils.findEntityManagerFactory(this.beanFactory, unitName);
|
||||
if (requestingBeanName != null && this.beanFactory instanceof ConfigurableBeanFactory) {
|
||||
((ConfigurableBeanFactory) this.beanFactory).registerDependentBean(unitName, requestingBeanName);
|
||||
@@ -557,6 +560,8 @@ public class PersistenceAnnotationBeanPostProcessor
|
||||
protected EntityManagerFactory findDefaultEntityManagerFactory(@Nullable String requestingBeanName)
|
||||
throws NoSuchBeanDefinitionException {
|
||||
|
||||
Assert.state(this.beanFactory != null, "ListableBeanFactory required for EntityManagerFactory bean lookup");
|
||||
|
||||
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
|
||||
// Fancy variant with dependency registration
|
||||
ConfigurableListableBeanFactory clbf = (ConfigurableListableBeanFactory) this.beanFactory;
|
||||
@@ -617,10 +622,12 @@ public class PersistenceAnnotationBeanPostProcessor
|
||||
|
||||
private final String unitName;
|
||||
|
||||
@Nullable
|
||||
private PersistenceContextType type;
|
||||
|
||||
private boolean synchronizedWithTransaction = false;
|
||||
|
||||
@Nullable
|
||||
private Properties properties;
|
||||
|
||||
public PersistenceElement(Member member, AnnotatedElement ae, @Nullable PropertyDescriptor pd) {
|
||||
|
||||
@@ -21,6 +21,7 @@ import javax.persistence.EntityManagerFactory;
|
||||
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.orm.jpa.EntityManagerFactoryAccessor;
|
||||
import org.springframework.orm.jpa.EntityManagerFactoryInfo;
|
||||
import org.springframework.orm.jpa.SharedEntityManagerCreator;
|
||||
@@ -51,10 +52,12 @@ import org.springframework.util.Assert;
|
||||
public class SharedEntityManagerBean extends EntityManagerFactoryAccessor
|
||||
implements FactoryBean<EntityManager>, InitializingBean {
|
||||
|
||||
@Nullable
|
||||
private Class<? extends EntityManager> entityManagerInterface;
|
||||
|
||||
private boolean synchronizedWithTransaction = true;
|
||||
|
||||
@Nullable
|
||||
private EntityManager shared;
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 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,6 +24,7 @@ import javax.persistence.PersistenceException;
|
||||
import org.eclipse.persistence.sessions.UnitOfWork;
|
||||
|
||||
import org.springframework.jdbc.datasource.ConnectionHandle;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.orm.jpa.DefaultJpaDialect;
|
||||
import org.springframework.transaction.TransactionDefinition;
|
||||
import org.springframework.transaction.TransactionException;
|
||||
@@ -114,6 +115,7 @@ public class EclipseLinkJpaDialect extends DefaultJpaDialect {
|
||||
|
||||
private final EntityManager entityManager;
|
||||
|
||||
@Nullable
|
||||
private Connection connection;
|
||||
|
||||
public EclipseLinkConnectionHandle(EntityManager entityManager) {
|
||||
|
||||
@@ -322,10 +322,13 @@ public class HibernateJpaDialect extends DefaultJpaDialect {
|
||||
|
||||
private final Session session;
|
||||
|
||||
@Nullable
|
||||
private final FlushMode previousFlushMode;
|
||||
|
||||
@Nullable
|
||||
private final Connection preparedCon;
|
||||
|
||||
@Nullable
|
||||
private final Integer previousIsolationLevel;
|
||||
|
||||
public SessionTransactionData(Session session, @Nullable FlushMode previousFlushMode,
|
||||
@@ -358,6 +361,7 @@ public class HibernateJpaDialect extends DefaultJpaDialect {
|
||||
|
||||
private static class HibernateConnectionHandle implements ConnectionHandle {
|
||||
|
||||
@Nullable
|
||||
private static volatile Method connectionMethodToUse;
|
||||
|
||||
private final Session session;
|
||||
@@ -377,11 +381,13 @@ public class HibernateJpaDialect extends DefaultJpaDialect {
|
||||
|
||||
public static Connection doGetConnection(Session session) {
|
||||
try {
|
||||
if (connectionMethodToUse == null) {
|
||||
Method methodToUse = connectionMethodToUse;
|
||||
if (methodToUse == null) {
|
||||
// Reflective lookup to find SessionImpl's connection() method on Hibernate 4.x/5.x
|
||||
connectionMethodToUse = session.getClass().getMethod("connection");
|
||||
methodToUse = session.getClass().getMethod("connection");
|
||||
connectionMethodToUse = methodToUse;
|
||||
}
|
||||
Connection con = (Connection) ReflectionUtils.invokeMethod(connectionMethodToUse, session);
|
||||
Connection con = (Connection) ReflectionUtils.invokeMethod(methodToUse, session);
|
||||
Assert.state(con != null, "No Connection from Session");
|
||||
return con;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user