Java Spring数据JPA CDI与多个持久化单元的集成
我是Spring新手,尝试在WebLogic12c上集成Spring数据、EclipseLink和EJB 我想使用CDI将Spring数据存储库注入到无状态EJB中,因此我遵循Spring数据CDI集成指令,并成功地使用了单个持久化单元 由于应用程序需要两个持久性单元来连接两个不同的数据库,因此我在persistence.xml中配置了两个具有不同名称的持久性单元 问题来了:我如何创建两个Spring数据存储库,以便Java Spring数据JPA CDI与多个持久化单元的集成,java,spring-data,spring-data-jpa,eclipselink,cdi,Java,Spring Data,Spring Data Jpa,Eclipselink,Cdi,我是Spring新手,尝试在WebLogic12c上集成Spring数据、EclipseLink和EJB 我想使用CDI将Spring数据存储库注入到无状态EJB中,因此我遵循Spring数据CDI集成指令,并成功地使用了单个持久化单元 由于应用程序需要两个持久性单元来连接两个不同的数据库,因此我在persistence.xml中配置了两个具有不同名称的持久性单元 问题来了:我如何创建两个Spring数据存储库,以便RepositoryA使用持久化单元A而RepositoryB使用持久化单元B
RepositoryA
使用持久化单元A而RepositoryB
使用持久化单元B
persistence.xml
<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">
<persistence-unit name="PRIMARY_PU" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/EMP_DS</jta-data-source>
<class>com.smec.eis.example.springbooteval.model.Employee</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
</persistence-unit>
<persistence-unit name="SECONDARY_PU" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/HR_DS</jta-data-source>
<class>com.smec.eis.example.springbooteval.model.Job</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
</persistence-unit>
</persistence>
TL;博士
使用限定符声明哪个存储库应该使用哪个EntityManager
解释
Spring数据JPA存储库默认在单个EntityManager
上实现。CDI扩展将任何限定符从存储库接口传播到其EntityManager
选择。由于限定符实际上是空的(不计入@Default
和@Any
),因此扩展使用上面代码中的单个EntityManager
创建和添加自己的限定符批注将为您完成以下工作:
限定词
存储库接口
您的EntityManagerFactoryProducer
:
上面的代码假设您使用的实体类型在两个数据源中不同。如果您需要使用相同的实体类型,那么您将创建一个基本存储库接口,用@NoRepositoryBean
和两个派生接口对其进行注释,类似于上面的代码。TL;博士
使用限定符声明哪个存储库应该使用哪个EntityManager
解释
Spring数据JPA存储库默认在单个EntityManager
上实现。CDI扩展将任何限定符从存储库接口传播到其EntityManager
选择。由于限定符实际上是空的(不计入@Default
和@Any
),因此扩展使用上面代码中的单个EntityManager
创建和添加自己的限定符批注将为您完成以下工作:
限定词
存储库接口
您的EntityManagerFactoryProducer
:
上面的代码假设您使用的实体类型在两个数据源中不同。如果您需要使用相同的实体类型,那么您将创建一个基本存储库接口,用
@NoRepositoryBean
和两个派生接口对其进行注释,类似于上面的代码。基于mp911de的答案。EntityManagerFactoryProducer需要两个更接近的方法,否则在Weblogic上部署失败
public class EntityManagerFactoryProducer {
@Produces
@ApplicationScoped
@PrimaryEM
public EntityManagerFactory createEntityManagerFactory() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("PRIMARY_PU");
return emf;
}
@Produces
@Dependent
@PrimaryEM
public EntityManager createEntityManager(@PrimaryEM EntityManagerFactory entityManagerFactory) {
EntityManager em = entityManagerFactory.createEntityManager();
return em;
}
@Produces
@ApplicationScoped
@SecondaryEM
public EntityManagerFactory createSecondaryEntityManagerFactory() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("SECONDARY_PU");
return emf;
}
@Produces
@Dependent
@SecondaryEM
public EntityManager createSecondaryEntityManager(@SecondaryEM EntityManagerFactory entityManagerFactory) {
EntityManager em = entityManagerFactory.createEntityManager();
return em;
}
public void close(@Disposes @PrimaryEM EntityManager entityManager) {
entityManager.close();
}
public void close(@Disposes @PrimaryEM EntityManagerFactory entityManagerFactory) {
entityManagerFactory.close();
}
public void closeSecondary(@Disposes @SecondaryEM EntityManager entityManager) {
entityManager.close();
}
public void closeSecondary(@Disposes @SecondaryEM EntityManagerFactory entityManagerFactory) {
entityManagerFactory.close();
}
基于mp911de的答案。EntityManagerFactoryProducer需要两个更接近的方法,否则在Weblogic上部署失败
public class EntityManagerFactoryProducer {
@Produces
@ApplicationScoped
@PrimaryEM
public EntityManagerFactory createEntityManagerFactory() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("PRIMARY_PU");
return emf;
}
@Produces
@Dependent
@PrimaryEM
public EntityManager createEntityManager(@PrimaryEM EntityManagerFactory entityManagerFactory) {
EntityManager em = entityManagerFactory.createEntityManager();
return em;
}
@Produces
@ApplicationScoped
@SecondaryEM
public EntityManagerFactory createSecondaryEntityManagerFactory() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("SECONDARY_PU");
return emf;
}
@Produces
@Dependent
@SecondaryEM
public EntityManager createSecondaryEntityManager(@SecondaryEM EntityManagerFactory entityManagerFactory) {
EntityManager em = entityManagerFactory.createEntityManager();
return em;
}
public void close(@Disposes @PrimaryEM EntityManager entityManager) {
entityManager.close();
}
public void close(@Disposes @PrimaryEM EntityManagerFactory entityManagerFactory) {
entityManagerFactory.close();
}
public void closeSecondary(@Disposes @SecondaryEM EntityManager entityManager) {
entityManager.close();
}
public void closeSecondary(@Disposes @SecondaryEM EntityManagerFactory entityManagerFactory) {
entityManagerFactory.close();
}
为什么要在JavaEE容器中使用Spring数据?看看DeltaSpike:DeltaSpike是完全适合JavaEEI的CDI扩展。我想看看DeltaSpike。但如果我想让Spring数据同时在JEE容器和Spring容器中工作,那么使用Spring数据作为数据访问层是否是合理的理由呢?当然!但我的意见是要么使用Spring,要么使用JavaEE。使用Spring,您可以使用任何servlet容器,如Tomcat或Spring。加上Spring提供了比普通JavaEEI更方便的功能,我尝试过DeltaSpike,我喜欢它。DeltaSpike似乎通过更好地支持容器管理的事务,使JEE容器中的事情变得更容易。因为我们使用的是EJB和CMT,所以DeltaSpike可能是更好的选择。DeltaSpike是CDI扩展,其中as Spring是一个依赖项注入容器,它与EJB和CDI竞争。我决不会把这两者混为一谈。为什么要在JavaEE容器中使用Spring数据?看看DeltaSpike:DeltaSpike是完全适合JavaEEI的CDI扩展。我想看看DeltaSpike。但如果我想让Spring数据同时在JEE容器和Spring容器中工作,那么使用Spring数据作为数据访问层是否是合理的理由呢?当然!但我的意见是要么使用Spring,要么使用JavaEE。使用Spring,您可以使用任何servlet容器,如Tomcat或Spring。加上Spring提供了比普通JavaEEI更方便的功能,我尝试过DeltaSpike,我喜欢它。DeltaSpike似乎通过更好地支持容器管理的事务,使JEE容器中的事情变得更容易。因为我们使用的是EJB和CMT,所以DeltaSpike可能是更好的选择。DeltaSpike是CDI扩展,其中as Spring是一个依赖项注入容器,它与EJB和CDI竞争。我决不会把这两个混为一谈。非常感谢你的解释!我明天会尝试解决方案。非常感谢您的解释!我明天会试试这个解决办法。
@MyFirstDatabase
public interface SomeRepository extends CrudRepository<MyEntity, Long> { … }
@MySecondDatabase
public interface SomeOtherRepository extends CrudRepository<OtherEntity, Long> { … }
public class MyComponent {
@Inject
@MyFirstDatabase
SomeRepository someRepo;
@Inject
@MySecondDatabase
SomeOtherRepository someOtherRepo;
}
public class EntityManagerFactoryProducer {
@Produces
@ApplicationScoped
@MyFirstDatabase
public EntityManagerFactory createEntityManagerFactory() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("PRIMARY_PU");
return emf;
}
@Produces
@ApplicationScoped
@MySecondDatabase
public EntityManagerFactory createEntityManagerFactory() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("SECONDARY_PU");
return emf;
}
public void close(@Disposes EntityManagerFactory entityManagerFactory) {
entityManagerFactory.close();
}
@Produces
@Dependent
@MyFirstDatabase
public EntityManager createEntityManager(@MyFirstDatabase EntityManagerFactory entityManagerFactory) {
return entityManagerFactory.createEntityManager();
}
@Produces
@Dependent
@MySecondDatabase
public EntityManager createEntityManager(@MySecondDatabase EntityManagerFactory entityManagerFactory) {
return entityManagerFactory.createEntityManager();
}
public void close(@Disposes EntityManager entityManager) {
entityManager.close();
}
}
public class EntityManagerFactoryProducer {
@Produces
@ApplicationScoped
@PrimaryEM
public EntityManagerFactory createEntityManagerFactory() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("PRIMARY_PU");
return emf;
}
@Produces
@Dependent
@PrimaryEM
public EntityManager createEntityManager(@PrimaryEM EntityManagerFactory entityManagerFactory) {
EntityManager em = entityManagerFactory.createEntityManager();
return em;
}
@Produces
@ApplicationScoped
@SecondaryEM
public EntityManagerFactory createSecondaryEntityManagerFactory() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("SECONDARY_PU");
return emf;
}
@Produces
@Dependent
@SecondaryEM
public EntityManager createSecondaryEntityManager(@SecondaryEM EntityManagerFactory entityManagerFactory) {
EntityManager em = entityManagerFactory.createEntityManager();
return em;
}
public void close(@Disposes @PrimaryEM EntityManager entityManager) {
entityManager.close();
}
public void close(@Disposes @PrimaryEM EntityManagerFactory entityManagerFactory) {
entityManagerFactory.close();
}
public void closeSecondary(@Disposes @SecondaryEM EntityManager entityManager) {
entityManager.close();
}
public void closeSecondary(@Disposes @SecondaryEM EntityManagerFactory entityManagerFactory) {
entityManagerFactory.close();
}