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.BeanNameAware;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.SmartFactoryBean;
|
||||
import org.springframework.beans.factory.SmartInitializingSingleton;
|
||||
import org.springframework.core.task.AsyncTaskExecutor;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
|
@ -66,7 +66,9 @@ import org.springframework.util.CollectionUtils;
|
|||
/**
|
||||
* Abstract {@link org.springframework.beans.factory.FactoryBean} that creates
|
||||
* 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
|
||||
* contracts (standalone as well as container).
|
||||
|
@ -91,7 +93,7 @@ import org.springframework.util.CollectionUtils;
|
|||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public abstract class AbstractEntityManagerFactoryBean implements
|
||||
FactoryBean<EntityManagerFactory>, BeanClassLoaderAware, BeanFactoryAware,
|
||||
SmartFactoryBean<EntityManagerFactory>, BeanClassLoaderAware, BeanFactoryAware,
|
||||
BeanNameAware, InitializingBean, SmartInitializingSingleton, DisposableBean,
|
||||
EntityManagerFactoryInfo, PersistenceExceptionTranslator, Serializable {
|
||||
|
||||
|
@ -131,6 +133,9 @@ public abstract class AbstractEntityManagerFactoryBean implements
|
|||
/** Exposed client-level EntityManagerFactory proxy. */
|
||||
private @Nullable EntityManagerFactory entityManagerFactory;
|
||||
|
||||
/** Exposed client-level shared EntityManager proxy. */
|
||||
private @Nullable EntityManager sharedEntityManager;
|
||||
|
||||
|
||||
/**
|
||||
* Set the PersistenceProvider implementation class to use for creating the
|
||||
|
@ -333,11 +338,19 @@ public abstract class AbstractEntityManagerFactoryBean implements
|
|||
this.beanFactory = beanFactory;
|
||||
}
|
||||
|
||||
protected @Nullable BeanFactory getBeanFactory() {
|
||||
return this.beanFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanName(String name) {
|
||||
this.beanName = name;
|
||||
}
|
||||
|
||||
protected @Nullable String getBeanName() {
|
||||
return this.beanName;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws PersistenceException {
|
||||
|
@ -386,6 +399,7 @@ public abstract class AbstractEntityManagerFactoryBean implements
|
|||
// application-managed EntityManager proxy that automatically joins
|
||||
// existing transactions.
|
||||
this.entityManagerFactory = createEntityManagerFactoryProxy(this.nativeEntityManagerFactory);
|
||||
this.sharedEntityManager = SharedEntityManagerCreator.createSharedEntityManager(this.entityManagerFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -621,9 +635,23 @@ public abstract class AbstractEntityManagerFactoryBean implements
|
|||
return (this.entityManagerFactory != null ? this.entityManagerFactory.getClass() : EntityManagerFactory.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return either the singleton EntityManagerFactory or the shared EntityManager proxy.
|
||||
*/
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
public <S> @Nullable S getObject(Class<S> type) throws Exception {
|
||||
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;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import jakarta.persistence.EntityManagerFactory;
|
||||
|
@ -27,6 +29,11 @@ import jakarta.persistence.spi.PersistenceUnitInfo;
|
|||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
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.weaving.LoadTimeWeaverAware;
|
||||
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.util.Assert;
|
||||
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
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -52,6 +52,10 @@ public class MutablePersistenceUnitInfo implements SmartPersistenceUnitInfo {
|
|||
|
||||
private @Nullable String persistenceProviderClassName;
|
||||
|
||||
private @Nullable String scopeAnnotationName;
|
||||
|
||||
private final List<String> qualifierAnnotationNames = new ArrayList<>();
|
||||
|
||||
private @Nullable PersistenceUnitTransactionType transactionType;
|
||||
|
||||
private @Nullable DataSource nonJtaDataSource;
|
||||
|
@ -76,7 +80,7 @@ public class MutablePersistenceUnitInfo implements SmartPersistenceUnitInfo {
|
|||
|
||||
private Properties properties = new Properties();
|
||||
|
||||
private String persistenceXMLSchemaVersion = "2.0";
|
||||
private String persistenceXMLSchemaVersion = "3.2";
|
||||
|
||||
private @Nullable String persistenceProviderPackageName;
|
||||
|
||||
|
@ -99,6 +103,24 @@ public class MutablePersistenceUnitInfo implements SmartPersistenceUnitInfo {
|
|||
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) {
|
||||
this.transactionType = transactionType;
|
||||
}
|
||||
|
@ -276,16 +298,6 @@ public class MutablePersistenceUnitInfo implements SmartPersistenceUnitInfo {
|
|||
throw new UnsupportedOperationException("getNewTempClassLoader not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String getScopeAnnotationName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable List<String> getQualifierAnnotationNames() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
|
|
@ -61,28 +61,32 @@ final class PersistenceUnitReader {
|
|||
|
||||
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 SCOPE = "scope";
|
||||
|
||||
private static final String QUALIFIER = "qualifier";
|
||||
|
||||
private static final String TRANSACTION_TYPE = "transaction-type";
|
||||
|
||||
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 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 SHARED_CACHE_MODE = "shared-cache-mode";
|
||||
|
||||
private static final String VALIDATION_MODE = "validation-mode";
|
||||
|
||||
private static final String PROPERTIES = "properties";
|
||||
|
||||
private static final String META_INF = "META-INF";
|
||||
|
||||
|
||||
|
@ -200,6 +204,18 @@ final class PersistenceUnitReader {
|
|||
// set unit name
|
||||
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
|
||||
String txType = persistenceUnit.getAttribute(TRANSACTION_TYPE).trim();
|
||||
if (StringUtils.hasText(txType)) {
|
||||
|
@ -217,12 +233,6 @@ final class PersistenceUnitReader {
|
|||
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
|
||||
Element excludeUnlistedClasses = DomUtils.getChildElementByTagName(persistenceUnit, EXCLUDE_UNLISTED_CLASSES);
|
||||
if (excludeUnlistedClasses != null) {
|
||||
|
@ -242,39 +252,24 @@ final class PersistenceUnitReader {
|
|||
unitInfo.setValidationMode(ValidationMode.valueOf(validationMode));
|
||||
}
|
||||
|
||||
parseProperties(persistenceUnit, unitInfo);
|
||||
parseManagedClasses(persistenceUnit, unitInfo);
|
||||
parseQualifiers(persistenceUnit, unitInfo);
|
||||
parseMappingFiles(persistenceUnit, unitInfo);
|
||||
parseJarFiles(persistenceUnit, unitInfo);
|
||||
parseManagedClasses(persistenceUnit, unitInfo);
|
||||
parseProperties(persistenceUnit, unitInfo);
|
||||
|
||||
return unitInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the {@code property} XML elements.
|
||||
* Parse the {@code qualifier} 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the {@code class} XML elements.
|
||||
*/
|
||||
void parseManagedClasses(Element persistenceUnit, SpringPersistenceUnitInfo unitInfo) {
|
||||
List<Element> classes = DomUtils.getChildElementsByTagName(persistenceUnit, MANAGED_CLASS_NAME);
|
||||
void parseQualifiers(Element persistenceUnit, SpringPersistenceUnitInfo unitInfo) {
|
||||
List<Element> classes = DomUtils.getChildElementsByTagName(persistenceUnit, QUALIFIER);
|
||||
for (Element element : classes) {
|
||||
String value = DomUtils.getTextValue(element).trim();
|
||||
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
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.springframework.core.io.Resource;
|
|||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
|
||||
import org.springframework.orm.jpa.domain.MyDomain;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.TransactionException;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
|
@ -70,10 +71,14 @@ public abstract class AbstractEntityManagerFactoryIntegrationTests {
|
|||
private boolean zappedTables = false;
|
||||
|
||||
|
||||
@Autowired
|
||||
@Autowired @MyDomain
|
||||
public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
|
||||
this.entityManagerFactory = entityManagerFactory;
|
||||
this.sharedEntityManager = SharedEntityManagerCreator.createSharedEntityManager(this.entityManagerFactory);
|
||||
}
|
||||
|
||||
@Autowired @MyDomain
|
||||
public void setSharedEntityManager(EntityManager sharedEntityManager) {
|
||||
this.sharedEntityManager = sharedEntityManager;
|
||||
}
|
||||
|
||||
@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"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence https://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
|
||||
version="1.0">
|
||||
<persistence xmlns="https://jakarta.ee/xml/ns/persistence" version="3.2">
|
||||
|
||||
<persistence-unit name="Person" transaction-type="RESOURCE_LOCAL">
|
||||
<class>org.springframework.orm.jpa.domain.DriversLicense</class>
|
||||
<class>org.springframework.orm.jpa.domain.Person</class>
|
||||
<exclude-unlisted-classes/>
|
||||
<qualifier>org.springframework.orm.jpa.domain.MyDomain</qualifier>
|
||||
</persistence-unit>
|
||||
|
||||
</persistence>
|
|
@ -1,11 +1,10 @@
|
|||
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence https://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
|
||||
version="1.0">
|
||||
<persistence xmlns="https://jakarta.ee/xml/ns/persistence" version="3.2">
|
||||
|
||||
<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.Person</class>
|
||||
<exclude-unlisted-classes/>
|
||||
<qualifier>org.springframework.orm.jpa.domain.MyDomain</qualifier>
|
||||
</persistence-unit>
|
||||
|
||||
</persistence>
|
|
@ -18,6 +18,12 @@
|
|||
<prop key="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</prop>
|
||||
</props>
|
||||
</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 id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
|
||||
|
|
|
@ -3,10 +3,6 @@
|
|||
|
||||
<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">
|
||||
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
|
||||
<property name="url" value="jdbc:hsqldb:mem:xdb"/>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?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>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
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">
|
||||
<property name="persistenceXmlLocations" value="org/springframework/orm/jpa/domain/persistence-multi.xml"/>
|
||||
|
@ -16,6 +16,7 @@
|
|||
|
||||
<bean id="entityManagerFactory" parent="abstractEMF">
|
||||
<property name="persistenceUnitName" value="Drivers"/>
|
||||
<qualifier type="org.springframework.orm.jpa.domain.MyDomain"/>
|
||||
</bean>
|
||||
|
||||
<bean id="entityManagerFactory2" parent="abstractEMF">
|
||||
|
|
Loading…
Reference in New Issue