@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:
Juergen Hoeller
2017-06-30 01:53:45 +02:00
parent c4694c3f5c
commit cc74a2891a
936 changed files with 6090 additions and 2806 deletions

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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));

View File

@@ -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) {

View File

@@ -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();
}
}
}

View File

@@ -94,6 +94,7 @@ public class LocalSessionFactoryBuilder extends Configuration {
private final ResourcePatternResolver resourcePatternResolver;
@Nullable
private TypeFilter[] entityTypeFilters = DEFAULT_ENTITY_TYPE_FILTERS;

View File

@@ -40,8 +40,10 @@ public class SessionHolder extends ResourceHolderSupport {
private final Session session;
@Nullable
private Transaction transaction;
@Nullable
private FlushMode previousFlushMode;

View File

@@ -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();

View File

@@ -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;
}

View File

@@ -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();
}

View File

@@ -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;

View File

@@ -41,6 +41,7 @@ public class EntityManagerHolder extends ResourceHolderSupport {
private boolean transactionActive;
@Nullable
private SavepointManager savepointManager;

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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();

View File

@@ -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;
}

View File

@@ -38,8 +38,10 @@ import org.springframework.util.Assert;
*/
class SpringPersistenceUnitInfo extends MutablePersistenceUnitInfo {
@Nullable
private LoadTimeWeaver loadTimeWeaver;
@Nullable
private ClassLoader classLoader;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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;
}
/**

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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;
}