【问题标题】:Injecting a Stateless EJB into another Stateless and using PersistenceContext将无状态 EJB 注入另一个无状态并使用 PersistenceContext
【发布时间】:2020-06-02 13:48:27
【问题描述】:

有了 JEE 5 / EJB 3.0,Java 开发人员的生活变得更加轻松。后来,受Spring和CDI的影响,JEE也采用了类似的方法。 现在,我希望我做得对,但只是为了确定: 我有几个无状态 EJB,它们都查询和/或修改数据库。一个例子是

@Stateless
public class AddressDBService {

    @PersistenceContext
    protected EntityManager em;

一些无状态 EJB 像这样引用其他服务:

@Stateless
public class AVeDBService  {

@PersistenceContext
protected EntityManager em;

@Inject
private HomeToDealDBService homeToDealDBService;

@Inject
private AddressDBService addressDBservice;

在无状态 EJB 中,我有如下公共方法:

   @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
   public void saveEntity(Home home) throws EntityExistsException {
     this.em.persist(home);
     addressDBservice.saveAddress(home.getMainAddress(), home);
   }

虽然我几乎可以肯定这种用法是正确的并且是线程安全的(上述服务依次注入到 JSF Managed Beans 中)。 有人可以确认我的用法是正确的、线程安全的并且符合良好做法吗?

我的用法似乎符合以下问题:

Is EntityManager really thread-safe?

Stateless EJB with more injected EJBs instances

【问题讨论】:

    标签: jpa jakarta-ee java-ee-7 persistence.xml ejb-3.2


    【解决方案1】:

    “正确吗?”如果不知道项目的目标,就无法回答问题。 它可以工作吗?是的,您发布了可以部署的 java-ee 代码,但还不够。

    我通常使用 BCE(边界控制实体)模式和域驱动模式。 在此模式中,我们将 EJB 用于业务逻辑服务或端点 (JAX-RS),所有其他注入(即控制部分)都是 CDI 对象。

    实体(JPA)可以使用级联来避免手动保存相关实体:

    addressDBservice.saveAddress(home.getMainAddress(), home);

    如果您这样定义实体,则可以避免:

    @Entity
    public class Home {
        @ManyToOne(cascade=ALL)
        private Address mainAddress;
    }
    

    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) 注释通常响应特定的事务行为,不是必需的,所以只有当你想做的时候才是正确的。

    【讨论】:

    • “正确吗?”如果 EJB 和 CDI 可以按照指定的方式协同工作,我的意思是主要的。
    • 您只谈论“无状态 EJB”,我的意思是它可能是正确的,但是您可以将简单的 CDI 用于控制服务,但“正确”的方式不仅仅是最佳实践模式
    猜你喜欢
    • 2023-03-31
    • 2017-10-26
    • 1970-01-01
    • 2013-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-31
    相关资源
    最近更新 更多