【问题标题】:CDI Beans and JPA TransactionsCDI Bean 和 JPA 事务
【发布时间】:2017-08-17 04:28:50
【问题描述】:

例如用作 cdi 应用程序范围的 bean 是否应该包含 jpa 读/写内容,或者我应该始终将 EJB 用于 db 内容?我在互联网上的某个地方读到 cdi 不应包含 db 的东西。这是真的吗?

【问题讨论】:

  • 一般来说,一个句子在互联网上并不能成为一个好问题。您可以在问题中添加一些上下文吗?
  • 好的,我添加了更多,请看一下

标签: java jpa cdi


【解决方案1】:

是的,如果您使用任何 JavaEE 7 plus 版本或 JakartaEE,您可以使用 @Transactional InterceptorBinding 管理 CDI bean 上的数据库内容

看看Javadoc:@Transactional

以下是注入 EntityManager 和 CDI 而没有 EJB 的步骤

  1. 首先创建一个生产者来产生EntityManager。

    public class EntityManagerProducer {
      @PersistenceContext(name = "customer-orders-unit")    
      private EntityManager em;
    
      @Produces
      @RequestScoped
      public EntityManager getEntityManager() {
        return em;
      }
    }
    
  2. 创建您的 bean 以执行 DAO 操作。

    public MyCDIBeanDao{
      @Inject
      private EntityManager m_entityManager;
    
      @Transactional
      public doStuff(){
        // Here you are in a Container managed Transaction
        m_entityManager.persist(...)
      }
    }
    
  3. 不要忘记将beans.xml 添加到您的WEB-INF 文件夹中。

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
           xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
           http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd" 
           bean-discovery-mode="all" 
           version="2.0">
    </beans>
    

【讨论】:

  • 这应该是 OP 问题的公认答案。
【解决方案2】:

答案总是取决于...这取决于您的具体用例。

在 Java EE 中,我们使用 @EJB bean 作为注入 EntityManager 以便稍后在 JPA 实体上执行读/写的地方。 我们为什么这样做?因为我们需要Transactions。默认情况下,当您使用 @Stateless 注释 bean 时,其中的所有方法都是 Transactional 并且您可以免费获得它们。事务使您能够以原子方式更新多个表,它们要么全部成功,要么失败。

示例: 在您的方法updateABC()您想要更新表 A、B、C 并且您希望它们全部成功或回滚事务:

@Stateless
public class MyClass{
    @PersistenceContext
    EntityManager em;

    public void updateABC(){
       A a= em.find(A.class, aId);
       //here update some fields on the entity "a"

       B b= em.find(B.class, bId);
       //here update some fields on the entity "b"
       C c= em.find(C.class, cId);
       //here update some fields on the entity "c"
    }
}

就是这样……你已经完成了。您的所有更新都将神奇地保存到数据库中,否则什么也不会。

你需要这样的东西吗?去 EJB 的。 你不需要?您想手动完成这项工作吗?然后创建自己的 bean...

【讨论】:

  • 但我更喜欢 cdi 而不是 ejb .. 在这里使用 cdi 做同样的事情吗??
  • 你喜欢 CDI 多于 EJB 是什么意思?它们服务于不同的目的。在您的用例中,EJB 是正确的技术。当然,您可以在 CDI bean 中自己完成,但您需要手动实现事务边界,这意味着您将手动将 CDI 转换为 EJB……如果您想这样做,请继续。
  • cdi 的用途是什么?
  • CDI 有很多功能(取决于您使用的 CDI 版本)。然而最基本的是:强大且类型安全的 DI(依赖注入)、拦截器、装饰器、事件等。然而 EJB 具有额外的功能。阅读这篇博文,可能会澄清一些想法:blog.dblevins.com/2012/11/cdi-when-to-break-out-ejbs.html
  • @Alboz:没有。使用@TransactionalInterceptorBinding,你无事可做。只需注释您的方法(在容器管理的 bean 上)即可。它是 EJB 事务管理的替代方案。而且你不必管理 UseTransaction,这就是拦截器所做的。
猜你喜欢
  • 2014-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-19
  • 2015-02-12
  • 2013-07-24
相关资源
最近更新 更多