Support for qualified EntityManager/EntityManagerFactory injection (JPA 3.2)
Closes gh-33414
This commit is contained in:
parent
b0eacd22e0
commit
04f3975e0f
|
@ -53,8 +53,8 @@ import org.springframework.beans.factory.BeanFactory;
|
||||||
import org.springframework.beans.factory.BeanFactoryAware;
|
import org.springframework.beans.factory.BeanFactoryAware;
|
||||||
import org.springframework.beans.factory.BeanNameAware;
|
import org.springframework.beans.factory.BeanNameAware;
|
||||||
import org.springframework.beans.factory.DisposableBean;
|
import org.springframework.beans.factory.DisposableBean;
|
||||||
import org.springframework.beans.factory.FactoryBean;
|
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.beans.factory.SmartFactoryBean;
|
||||||
import org.springframework.beans.factory.SmartInitializingSingleton;
|
import org.springframework.beans.factory.SmartInitializingSingleton;
|
||||||
import org.springframework.core.task.AsyncTaskExecutor;
|
import org.springframework.core.task.AsyncTaskExecutor;
|
||||||
import org.springframework.dao.DataAccessException;
|
import org.springframework.dao.DataAccessException;
|
||||||
|
@ -66,7 +66,9 @@ import org.springframework.util.CollectionUtils;
|
||||||
/**
|
/**
|
||||||
* Abstract {@link org.springframework.beans.factory.FactoryBean} that creates
|
* Abstract {@link org.springframework.beans.factory.FactoryBean} that creates
|
||||||
* a local JPA {@link jakarta.persistence.EntityManagerFactory} instance within
|
* a local JPA {@link jakarta.persistence.EntityManagerFactory} instance within
|
||||||
* a Spring application context.
|
* a Spring application context. As of 7.0, it additionally exposes a shared
|
||||||
|
* {@link jakarta.persistence.EntityManager} instance through {@link SmartFactoryBean},
|
||||||
|
* making {@code EntityManager} available for dependency injection as well.
|
||||||
*
|
*
|
||||||
* <p>Encapsulates the common functionality between the different JPA bootstrap
|
* <p>Encapsulates the common functionality between the different JPA bootstrap
|
||||||
* contracts (standalone as well as container).
|
* contracts (standalone as well as container).
|
||||||
|
@ -91,7 +93,7 @@ import org.springframework.util.CollectionUtils;
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public abstract class AbstractEntityManagerFactoryBean implements
|
public abstract class AbstractEntityManagerFactoryBean implements
|
||||||
FactoryBean<EntityManagerFactory>, BeanClassLoaderAware, BeanFactoryAware,
|
SmartFactoryBean<EntityManagerFactory>, BeanClassLoaderAware, BeanFactoryAware,
|
||||||
BeanNameAware, InitializingBean, SmartInitializingSingleton, DisposableBean,
|
BeanNameAware, InitializingBean, SmartInitializingSingleton, DisposableBean,
|
||||||
EntityManagerFactoryInfo, PersistenceExceptionTranslator, Serializable {
|
EntityManagerFactoryInfo, PersistenceExceptionTranslator, Serializable {
|
||||||
|
|
||||||
|
@ -131,6 +133,9 @@ public abstract class AbstractEntityManagerFactoryBean implements
|
||||||
/** Exposed client-level EntityManagerFactory proxy. */
|
/** Exposed client-level EntityManagerFactory proxy. */
|
||||||
private @Nullable EntityManagerFactory entityManagerFactory;
|
private @Nullable EntityManagerFactory entityManagerFactory;
|
||||||
|
|
||||||
|
/** Exposed client-level shared EntityManager proxy. */
|
||||||
|
private @Nullable EntityManager sharedEntityManager;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the PersistenceProvider implementation class to use for creating the
|
* Set the PersistenceProvider implementation class to use for creating the
|
||||||
|
@ -333,11 +338,19 @@ public abstract class AbstractEntityManagerFactoryBean implements
|
||||||
this.beanFactory = beanFactory;
|
this.beanFactory = beanFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected @Nullable BeanFactory getBeanFactory() {
|
||||||
|
return this.beanFactory;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setBeanName(String name) {
|
public void setBeanName(String name) {
|
||||||
this.beanName = name;
|
this.beanName = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected @Nullable String getBeanName() {
|
||||||
|
return this.beanName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterPropertiesSet() throws PersistenceException {
|
public void afterPropertiesSet() throws PersistenceException {
|
||||||
|
@ -386,6 +399,7 @@ public abstract class AbstractEntityManagerFactoryBean implements
|
||||||
// application-managed EntityManager proxy that automatically joins
|
// application-managed EntityManager proxy that automatically joins
|
||||||
// existing transactions.
|
// existing transactions.
|
||||||
this.entityManagerFactory = createEntityManagerFactoryProxy(this.nativeEntityManagerFactory);
|
this.entityManagerFactory = createEntityManagerFactoryProxy(this.nativeEntityManagerFactory);
|
||||||
|
this.sharedEntityManager = SharedEntityManagerCreator.createSharedEntityManager(this.entityManagerFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -621,9 +635,23 @@ public abstract class AbstractEntityManagerFactoryBean implements
|
||||||
return (this.entityManagerFactory != null ? this.entityManagerFactory.getClass() : EntityManagerFactory.class);
|
return (this.entityManagerFactory != null ? this.entityManagerFactory.getClass() : EntityManagerFactory.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return either the singleton EntityManagerFactory or the shared EntityManager proxy.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isSingleton() {
|
public <S> @Nullable S getObject(Class<S> type) throws Exception {
|
||||||
return true;
|
if (EntityManager.class.isAssignableFrom(type)) {
|
||||||
|
return (type.isInstance(this.sharedEntityManager) ? type.cast(this.sharedEntityManager) : null);
|
||||||
|
}
|
||||||
|
return SmartFactoryBean.super.getObject(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supportsType(Class<?> type) {
|
||||||
|
if (EntityManager.class.isAssignableFrom(type)) {
|
||||||
|
return type.isInstance(this.sharedEntityManager);
|
||||||
|
}
|
||||||
|
return SmartFactoryBean.super.supportsType(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
package org.springframework.orm.jpa;
|
package org.springframework.orm.jpa;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
import jakarta.persistence.EntityManagerFactory;
|
import jakarta.persistence.EntityManagerFactory;
|
||||||
|
@ -27,6 +29,11 @@ import jakarta.persistence.spi.PersistenceUnitInfo;
|
||||||
import org.jspecify.annotations.Nullable;
|
import org.jspecify.annotations.Nullable;
|
||||||
|
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
|
import org.springframework.beans.factory.BeanFactory;
|
||||||
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||||
|
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||||
|
import org.springframework.beans.factory.support.AutowireCandidateQualifier;
|
||||||
import org.springframework.context.ResourceLoaderAware;
|
import org.springframework.context.ResourceLoaderAware;
|
||||||
import org.springframework.context.weaving.LoadTimeWeaverAware;
|
import org.springframework.context.weaving.LoadTimeWeaverAware;
|
||||||
import org.springframework.core.io.ResourceLoader;
|
import org.springframework.core.io.ResourceLoader;
|
||||||
|
@ -40,6 +47,8 @@ import org.springframework.orm.jpa.persistenceunit.PersistenceUnitPostProcessor;
|
||||||
import org.springframework.orm.jpa.persistenceunit.SmartPersistenceUnitInfo;
|
import org.springframework.orm.jpa.persistenceunit.SmartPersistenceUnitInfo;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link org.springframework.beans.factory.FactoryBean} that creates a JPA
|
* {@link org.springframework.beans.factory.FactoryBean} that creates a JPA
|
||||||
|
@ -361,6 +370,25 @@ public class LocalContainerEntityManagerFactoryBean extends AbstractEntityManage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String scope = this.persistenceUnitInfo.getScopeAnnotationName();
|
||||||
|
if (StringUtils.hasText(scope)) {
|
||||||
|
logger.info("Scope annotation name for persistence unit ignored by Spring: " + scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> qualifiers = this.persistenceUnitInfo.getQualifierAnnotationNames();
|
||||||
|
if (!CollectionUtils.isEmpty(qualifiers)) {
|
||||||
|
BeanFactory beanFactory = getBeanFactory();
|
||||||
|
String beanName = getBeanName();
|
||||||
|
if (beanFactory instanceof ConfigurableBeanFactory cbf && beanName != null) {
|
||||||
|
BeanDefinition bd = cbf.getMergedBeanDefinition(beanName);
|
||||||
|
if (bd instanceof AbstractBeanDefinition abd) {
|
||||||
|
for (String qualifier : qualifiers) {
|
||||||
|
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
super.afterPropertiesSet();
|
super.afterPropertiesSet();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,10 @@ public class MutablePersistenceUnitInfo implements SmartPersistenceUnitInfo {
|
||||||
|
|
||||||
private @Nullable String persistenceProviderClassName;
|
private @Nullable String persistenceProviderClassName;
|
||||||
|
|
||||||
|
private @Nullable String scopeAnnotationName;
|
||||||
|
|
||||||
|
private final List<String> qualifierAnnotationNames = new ArrayList<>();
|
||||||
|
|
||||||
private @Nullable PersistenceUnitTransactionType transactionType;
|
private @Nullable PersistenceUnitTransactionType transactionType;
|
||||||
|
|
||||||
private @Nullable DataSource nonJtaDataSource;
|
private @Nullable DataSource nonJtaDataSource;
|
||||||
|
@ -76,7 +80,7 @@ public class MutablePersistenceUnitInfo implements SmartPersistenceUnitInfo {
|
||||||
|
|
||||||
private Properties properties = new Properties();
|
private Properties properties = new Properties();
|
||||||
|
|
||||||
private String persistenceXMLSchemaVersion = "2.0";
|
private String persistenceXMLSchemaVersion = "3.2";
|
||||||
|
|
||||||
private @Nullable String persistenceProviderPackageName;
|
private @Nullable String persistenceProviderPackageName;
|
||||||
|
|
||||||
|
@ -99,6 +103,24 @@ public class MutablePersistenceUnitInfo implements SmartPersistenceUnitInfo {
|
||||||
return this.persistenceProviderClassName;
|
return this.persistenceProviderClassName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setScopeAnnotationName(@Nullable String scopeAnnotationName) {
|
||||||
|
this.scopeAnnotationName = scopeAnnotationName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable String getScopeAnnotationName() {
|
||||||
|
return this.scopeAnnotationName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addQualifierAnnotationName(String qualifierAnnotationName) {
|
||||||
|
this.qualifierAnnotationNames.add(qualifierAnnotationName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getQualifierAnnotationNames() {
|
||||||
|
return this.qualifierAnnotationNames;
|
||||||
|
}
|
||||||
|
|
||||||
public void setTransactionType(PersistenceUnitTransactionType transactionType) {
|
public void setTransactionType(PersistenceUnitTransactionType transactionType) {
|
||||||
this.transactionType = transactionType;
|
this.transactionType = transactionType;
|
||||||
}
|
}
|
||||||
|
@ -276,16 +298,6 @@ public class MutablePersistenceUnitInfo implements SmartPersistenceUnitInfo {
|
||||||
throw new UnsupportedOperationException("getNewTempClassLoader not supported");
|
throw new UnsupportedOperationException("getNewTempClassLoader not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public @Nullable String getScopeAnnotationName() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @Nullable List<String> getQualifierAnnotationNames() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
|
|
@ -61,28 +61,32 @@ final class PersistenceUnitReader {
|
||||||
|
|
||||||
private static final String UNIT_NAME = "name";
|
private static final String UNIT_NAME = "name";
|
||||||
|
|
||||||
private static final String MAPPING_FILE_NAME = "mapping-file";
|
|
||||||
|
|
||||||
private static final String JAR_FILE_URL = "jar-file";
|
|
||||||
|
|
||||||
private static final String MANAGED_CLASS_NAME = "class";
|
|
||||||
|
|
||||||
private static final String PROPERTIES = "properties";
|
|
||||||
|
|
||||||
private static final String PROVIDER = "provider";
|
private static final String PROVIDER = "provider";
|
||||||
|
|
||||||
|
private static final String SCOPE = "scope";
|
||||||
|
|
||||||
|
private static final String QUALIFIER = "qualifier";
|
||||||
|
|
||||||
private static final String TRANSACTION_TYPE = "transaction-type";
|
private static final String TRANSACTION_TYPE = "transaction-type";
|
||||||
|
|
||||||
private static final String JTA_DATA_SOURCE = "jta-data-source";
|
private static final String JTA_DATA_SOURCE = "jta-data-source";
|
||||||
|
|
||||||
private static final String NON_JTA_DATA_SOURCE = "non-jta-data-source";
|
private static final String NON_JTA_DATA_SOURCE = "non-jta-data-source";
|
||||||
|
|
||||||
|
private static final String MAPPING_FILE_NAME = "mapping-file";
|
||||||
|
|
||||||
|
private static final String JAR_FILE_URL = "jar-file";
|
||||||
|
|
||||||
|
private static final String MANAGED_CLASS_NAME = "class";
|
||||||
|
|
||||||
private static final String EXCLUDE_UNLISTED_CLASSES = "exclude-unlisted-classes";
|
private static final String EXCLUDE_UNLISTED_CLASSES = "exclude-unlisted-classes";
|
||||||
|
|
||||||
private static final String SHARED_CACHE_MODE = "shared-cache-mode";
|
private static final String SHARED_CACHE_MODE = "shared-cache-mode";
|
||||||
|
|
||||||
private static final String VALIDATION_MODE = "validation-mode";
|
private static final String VALIDATION_MODE = "validation-mode";
|
||||||
|
|
||||||
|
private static final String PROPERTIES = "properties";
|
||||||
|
|
||||||
private static final String META_INF = "META-INF";
|
private static final String META_INF = "META-INF";
|
||||||
|
|
||||||
|
|
||||||
|
@ -200,6 +204,18 @@ final class PersistenceUnitReader {
|
||||||
// set unit name
|
// set unit name
|
||||||
unitInfo.setPersistenceUnitName(persistenceUnit.getAttribute(UNIT_NAME).trim());
|
unitInfo.setPersistenceUnitName(persistenceUnit.getAttribute(UNIT_NAME).trim());
|
||||||
|
|
||||||
|
// provider
|
||||||
|
String provider = DomUtils.getChildElementValueByTagName(persistenceUnit, PROVIDER);
|
||||||
|
if (StringUtils.hasText(provider)) {
|
||||||
|
unitInfo.setPersistenceProviderClassName(provider.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
// scope
|
||||||
|
String scope = DomUtils.getChildElementValueByTagName(persistenceUnit, SCOPE);
|
||||||
|
if (StringUtils.hasText(scope)) {
|
||||||
|
unitInfo.setScopeAnnotationName(scope.trim());
|
||||||
|
}
|
||||||
|
|
||||||
// set transaction type
|
// set transaction type
|
||||||
String txType = persistenceUnit.getAttribute(TRANSACTION_TYPE).trim();
|
String txType = persistenceUnit.getAttribute(TRANSACTION_TYPE).trim();
|
||||||
if (StringUtils.hasText(txType)) {
|
if (StringUtils.hasText(txType)) {
|
||||||
|
@ -217,12 +233,6 @@ final class PersistenceUnitReader {
|
||||||
unitInfo.setNonJtaDataSource(this.dataSourceLookup.getDataSource(nonJtaDataSource.trim()));
|
unitInfo.setNonJtaDataSource(this.dataSourceLookup.getDataSource(nonJtaDataSource.trim()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// provider
|
|
||||||
String provider = DomUtils.getChildElementValueByTagName(persistenceUnit, PROVIDER);
|
|
||||||
if (StringUtils.hasText(provider)) {
|
|
||||||
unitInfo.setPersistenceProviderClassName(provider.trim());
|
|
||||||
}
|
|
||||||
|
|
||||||
// exclude unlisted classes
|
// exclude unlisted classes
|
||||||
Element excludeUnlistedClasses = DomUtils.getChildElementByTagName(persistenceUnit, EXCLUDE_UNLISTED_CLASSES);
|
Element excludeUnlistedClasses = DomUtils.getChildElementByTagName(persistenceUnit, EXCLUDE_UNLISTED_CLASSES);
|
||||||
if (excludeUnlistedClasses != null) {
|
if (excludeUnlistedClasses != null) {
|
||||||
|
@ -242,39 +252,24 @@ final class PersistenceUnitReader {
|
||||||
unitInfo.setValidationMode(ValidationMode.valueOf(validationMode));
|
unitInfo.setValidationMode(ValidationMode.valueOf(validationMode));
|
||||||
}
|
}
|
||||||
|
|
||||||
parseProperties(persistenceUnit, unitInfo);
|
parseQualifiers(persistenceUnit, unitInfo);
|
||||||
parseManagedClasses(persistenceUnit, unitInfo);
|
|
||||||
parseMappingFiles(persistenceUnit, unitInfo);
|
parseMappingFiles(persistenceUnit, unitInfo);
|
||||||
parseJarFiles(persistenceUnit, unitInfo);
|
parseJarFiles(persistenceUnit, unitInfo);
|
||||||
|
parseManagedClasses(persistenceUnit, unitInfo);
|
||||||
|
parseProperties(persistenceUnit, unitInfo);
|
||||||
|
|
||||||
return unitInfo;
|
return unitInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse the {@code property} XML elements.
|
* Parse the {@code qualifier} XML elements.
|
||||||
*/
|
*/
|
||||||
void parseProperties(Element persistenceUnit, SpringPersistenceUnitInfo unitInfo) {
|
void parseQualifiers(Element persistenceUnit, SpringPersistenceUnitInfo unitInfo) {
|
||||||
Element propRoot = DomUtils.getChildElementByTagName(persistenceUnit, PROPERTIES);
|
List<Element> classes = DomUtils.getChildElementsByTagName(persistenceUnit, QUALIFIER);
|
||||||
if (propRoot == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
List<Element> properties = DomUtils.getChildElementsByTagName(propRoot, "property");
|
|
||||||
for (Element property : properties) {
|
|
||||||
String name = property.getAttribute("name");
|
|
||||||
String value = property.getAttribute("value");
|
|
||||||
unitInfo.addProperty(name, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse the {@code class} XML elements.
|
|
||||||
*/
|
|
||||||
void parseManagedClasses(Element persistenceUnit, SpringPersistenceUnitInfo unitInfo) {
|
|
||||||
List<Element> classes = DomUtils.getChildElementsByTagName(persistenceUnit, MANAGED_CLASS_NAME);
|
|
||||||
for (Element element : classes) {
|
for (Element element : classes) {
|
||||||
String value = DomUtils.getTextValue(element).trim();
|
String value = DomUtils.getTextValue(element).trim();
|
||||||
if (StringUtils.hasText(value)) {
|
if (StringUtils.hasText(value)) {
|
||||||
unitInfo.addManagedClassName(value);
|
unitInfo.addQualifierAnnotationName(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -323,6 +318,35 @@ final class PersistenceUnitReader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the {@code class} XML elements.
|
||||||
|
*/
|
||||||
|
void parseManagedClasses(Element persistenceUnit, SpringPersistenceUnitInfo unitInfo) {
|
||||||
|
List<Element> classes = DomUtils.getChildElementsByTagName(persistenceUnit, MANAGED_CLASS_NAME);
|
||||||
|
for (Element element : classes) {
|
||||||
|
String value = DomUtils.getTextValue(element).trim();
|
||||||
|
if (StringUtils.hasText(value)) {
|
||||||
|
unitInfo.addManagedClassName(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the {@code property} XML elements.
|
||||||
|
*/
|
||||||
|
void parseProperties(Element persistenceUnit, SpringPersistenceUnitInfo unitInfo) {
|
||||||
|
Element propRoot = DomUtils.getChildElementByTagName(persistenceUnit, PROPERTIES);
|
||||||
|
if (propRoot == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
List<Element> properties = DomUtils.getChildElementsByTagName(propRoot, "property");
|
||||||
|
for (Element property : properties) {
|
||||||
|
String name = property.getAttribute("name");
|
||||||
|
String value = property.getAttribute("value");
|
||||||
|
unitInfo.addProperty(name, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine the persistence unit root URL based on the given resource
|
* Determine the persistence unit root URL based on the given resource
|
||||||
|
|
|
@ -32,6 +32,7 @@ import org.springframework.core.io.Resource;
|
||||||
import org.springframework.dao.DataAccessException;
|
import org.springframework.dao.DataAccessException;
|
||||||
import org.springframework.jdbc.core.JdbcTemplate;
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
|
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
|
||||||
|
import org.springframework.orm.jpa.domain.MyDomain;
|
||||||
import org.springframework.transaction.PlatformTransactionManager;
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
import org.springframework.transaction.TransactionException;
|
import org.springframework.transaction.TransactionException;
|
||||||
import org.springframework.transaction.TransactionStatus;
|
import org.springframework.transaction.TransactionStatus;
|
||||||
|
@ -70,10 +71,14 @@ public abstract class AbstractEntityManagerFactoryIntegrationTests {
|
||||||
private boolean zappedTables = false;
|
private boolean zappedTables = false;
|
||||||
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired @MyDomain
|
||||||
public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
|
public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
|
||||||
this.entityManagerFactory = entityManagerFactory;
|
this.entityManagerFactory = entityManagerFactory;
|
||||||
this.sharedEntityManager = SharedEntityManagerCreator.createSharedEntityManager(this.entityManagerFactory);
|
}
|
||||||
|
|
||||||
|
@Autowired @MyDomain
|
||||||
|
public void setSharedEntityManager(EntityManager sharedEntityManager) {
|
||||||
|
this.sharedEntityManager = sharedEntityManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-present 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.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.orm.jpa.domain;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
|
||||||
|
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Qualifier
|
||||||
|
public @interface MyDomain {
|
||||||
|
|
||||||
|
}
|
|
@ -1,11 +1,10 @@
|
||||||
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<persistence xmlns="https://jakarta.ee/xml/ns/persistence" version="3.2">
|
||||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence https://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
|
|
||||||
version="1.0">
|
|
||||||
|
|
||||||
<persistence-unit name="Person" transaction-type="RESOURCE_LOCAL">
|
<persistence-unit name="Person" transaction-type="RESOURCE_LOCAL">
|
||||||
<class>org.springframework.orm.jpa.domain.DriversLicense</class>
|
<class>org.springframework.orm.jpa.domain.DriversLicense</class>
|
||||||
<class>org.springframework.orm.jpa.domain.Person</class>
|
<class>org.springframework.orm.jpa.domain.Person</class>
|
||||||
<exclude-unlisted-classes />
|
<exclude-unlisted-classes/>
|
||||||
|
<qualifier>org.springframework.orm.jpa.domain.MyDomain</qualifier>
|
||||||
</persistence-unit>
|
</persistence-unit>
|
||||||
|
|
||||||
</persistence>
|
</persistence>
|
|
@ -1,11 +1,10 @@
|
||||||
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<persistence xmlns="https://jakarta.ee/xml/ns/persistence" version="3.2">
|
||||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence https://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
|
|
||||||
version="1.0">
|
|
||||||
|
|
||||||
<persistence-unit name="Person" transaction-type="RESOURCE_LOCAL">
|
<persistence-unit name="Person" transaction-type="RESOURCE_LOCAL">
|
||||||
<class>org.springframework.orm.jpa.domain.Person</class>
|
|
||||||
<class>org.springframework.orm.jpa.domain.DriversLicense</class>
|
<class>org.springframework.orm.jpa.domain.DriversLicense</class>
|
||||||
<exclude-unlisted-classes />
|
<class>org.springframework.orm.jpa.domain.Person</class>
|
||||||
|
<exclude-unlisted-classes/>
|
||||||
|
<qualifier>org.springframework.orm.jpa.domain.MyDomain</qualifier>
|
||||||
</persistence-unit>
|
</persistence-unit>
|
||||||
|
|
||||||
</persistence>
|
</persistence>
|
|
@ -18,6 +18,12 @@
|
||||||
<prop key="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</prop>
|
<prop key="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</prop>
|
||||||
</props>
|
</props>
|
||||||
</property>
|
</property>
|
||||||
|
<qualifier type="org.springframework.orm.jpa.domain.MyDomain"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="entityManager" class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
|
||||||
|
<property name="entityManagerFactory" ref="entityManagerFactory"/>
|
||||||
|
<qualifier type="org.springframework.orm.jpa.domain.MyDomain"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
|
<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
|
||||||
|
|
|
@ -3,10 +3,6 @@
|
||||||
|
|
||||||
<beans>
|
<beans>
|
||||||
|
|
||||||
<bean id="entityManager" class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
|
|
||||||
<property name="entityManagerFactory" ref="entityManagerFactory"/>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
|
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
|
||||||
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
|
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
|
||||||
<property name="url" value="jdbc:hsqldb:mem:xdb"/>
|
<property name="url" value="jdbc:hsqldb:mem:xdb"/>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "https://www.springframework.org/dtd/spring-beans-2.0.dtd">
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
<beans>
|
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
|
||||||
|
|
||||||
<bean id="persistenceUnitManager" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
|
<bean id="persistenceUnitManager" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
|
||||||
<property name="persistenceXmlLocations" value="org/springframework/orm/jpa/domain/persistence-multi.xml"/>
|
<property name="persistenceXmlLocations" value="org/springframework/orm/jpa/domain/persistence-multi.xml"/>
|
||||||
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
<bean id="entityManagerFactory" parent="abstractEMF">
|
<bean id="entityManagerFactory" parent="abstractEMF">
|
||||||
<property name="persistenceUnitName" value="Drivers"/>
|
<property name="persistenceUnitName" value="Drivers"/>
|
||||||
|
<qualifier type="org.springframework.orm.jpa.domain.MyDomain"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="entityManagerFactory2" parent="abstractEMF">
|
<bean id="entityManagerFactory2" parent="abstractEMF">
|
||||||
|
|
Loading…
Reference in New Issue