【问题标题】:Spring equivalent of @Stateless EJB with multiple @PersistenceContextSpring 等效于具有多个 @PersistenceContext 的 @Stateless EJB
【发布时间】:2015-06-02 13:18:11
【问题描述】:

在过去的几天里,我一直在用头撞墙,试图让它工作,但我没能做到。

我最近使用 EJB 编写了一个 JPA EntityManagerProvider:

EntityManagerProviderBean.java

@Stateless
public class EntityManagerProviderBean {

    @PersistenceContext(unitName="PU1")
    private EntityManager entityManager1;   

    @PersistenceContext(unitName="PU2")
    private EntityManager entityManager2;

    public EntityManager getEntityManager() {
        return (...) ? entityManager1: entityManager2;
    }
}

然后我当然可以像这样在任何需要的地方注入 EJB:

UserFacade.java

@Stateless
public class UserFacade {

    @EJB
    private EntityManagerProviderBean emProvider;
    private EntityManager em = emProvider.getEntityManager();

    ...
}

现在我正在尝试使用 Spring 做类似的事情,使用注解,而不在 XML 中做任何事情。我似乎无法找到注入 EntityManager 的方法。我所做的任何事情都会导致 NullPointerException。例如,我尝试在不依赖我的 EntityManagerProviderBean 的情况下手动注入 EntityManager,如下所示:

UserFacadeSpring.java

public class UserFacadeSpring {

    @PersistenceContext(unitName="PU1")
    private EntityManager em;

    ...
}

但这给了我一个 NullPointerException。所以 EntityManager 根本没有被注入,我不确定出了什么问题。

所以基本上是两个问题:

  1. 如何使用 Spring 注入 EntityManager?
  2. 如何在 Spring 中使用现有的 EntityManagerProviderBean EJB?我需要进行哪些修改?

在此问题上的任何帮助将不胜感激。正如你所知道的,我对 Spring 完全是个菜鸟。我试图阅读指南,但此刻一切都在我脑海中浮现。实际上,我确实尝试过做一些半生不熟的事情,但它也没有奏效(我得到 NullPointerException 或 BeanNotFoundException,我认为我一定使用了 @Component、@Bean、@Autowired 注释的所有组合!):

EntityManagerProviderSpring.java

@Component
public class EntityManagerProviderSpring {

    @PersistenceContext(unitName="PU1")
    private EntityManager entityManager1;   

    @PersistenceContext(unitName="PU2")
    private EntityManager entityManager2;

    @Bean
    public EntityManager getEntityManager() {
        return (...) ? entityManager1: entityManager2;
    }
}

Main.java

public class Main {
    public static void main(String[] args) {

    ApplicationContext context = new AnnotationConfigApplicationContext(EntityManagerProviderSpring.class);
    EntityManagerProviderSpring emProvider = context.getBean(EntityManagerProviderSpring.class);
    EntityManager em = emProvider.getEntityManager();

    ...
}

谢谢!

编辑:我将 Hibernate 与 JPA 一起使用,以下是我的 persistence.xml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" 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">
  <persistence-unit name="PU1" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <class>...</class>
    <properties>
      <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/db1?zeroDateTimeBehavior=convertToNull"/>
      <property name="javax.persistence.jdbc.user" value="pu1_username"/>
      <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
      <property name="javax.persistence.jdbc.password" value="pu1_pwd"/>
      <property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/>
    </properties>
  </persistence-unit>
  <persistence-unit name="PU2" transaction-type="RESOURCE_LOCAL">
    ...
  </persistence-unit>
</persistence>

【问题讨论】:

  • 基本上你在问,如何配置spring,使其注入多个PersistenceContexts。谷歌为“春天的两个实体经理”。
  • 谢谢,但仍有一些事情没有意义。是否绝对需要某种描述 bean 的 context.xml 文件?我将 Hibernate 与 JPA2 一起使用,并且有一个 persistence.xml 文件,其中定义了数据源,所以我认为这已经足够了?
  • 这东西相当基础。看看 spring 文档。

标签: spring jakarta-ee jpa


【解决方案1】:

要在依赖注入级别具有完全相同的功能,不可能将无状态 ejb bean 映射到 spring bean。

EJB @Singleton -> Spring @Component(或@Service 或@Controller 或@Repository)

EJB @Stateful -> Spring @Component@Scope("prototype") (或@Service@Scope("prototype") 或@Controller@Scope("prototype") 或@Repository@Scope("prototype"))

EJB @Stateless -> 在春季不存在。

无状态 bean 对于这种多重持久性上下文非常方便......但是,由于 Spring 不提供无状态 bean。您必须使用自定义 Spring 设置来应用多个持久性上下文。不幸的是,它不适用于像 EJB 这样的persistence.xml :(。

所以回答你的问题:

  1. 阅读 Spring 文档...到处都有大量示例。很快,在 Spring 4 Java Config 中,您可以使用@EnableTransactionManagement,每个持久化上下文的事务管理器和实体管理器工厂。
  2. http://docs.spring.io/spring/docs/current/spring-framework-reference/html/ejb.html。这就是你的做法。自从使用jndi 以来,这不是一个好方法,但它是一个解决方案...

【讨论】:

    猜你喜欢
    • 2015-12-05
    • 2012-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多