Внедрение Stateless EJB в другой Stateless и использование PersistenceContext

С 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). Может ли кто-нибудь подтвердить, что мое использование является правильным, потокобезопасным и соответствует передовой практике?

Мое использование, кажется, соответствует следующим вопросам:

Является ли EntityManager действительно потокобезопасным?

EJB без сохранения состояния с большим количеством внедренных экземпляров EJB


person Alex Mi    schedule 02.06.2020    source источник


Ответы (1)


"Правильно?" на вопрос нельзя ответить, не зная цели проекта. Это может работать? Да, вы разместили код java-ee, который можно развернуть, но этого недостаточно.

Я обычно использую шаблон BCE (Boundary Control Entity) и шаблон, управляемый доменом. В этом шаблоне мы используем EJB для служб бизнес-логики или конечной точки (JAX-RS), а все остальные инъекции, которые являются частью управления, являются объектами CDI.

Сущности (JPA) могут использовать каскад, чтобы избежать ручного сохранения связанных сущностей:

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

можно избежать, если вы определяете сущность следующим образом:

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

Аннотация @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) обычно отвечает на определенное поведение транзакций, не требуется, поэтому она верна, только если это то, что вы хотите сделать.

person fantarama    schedule 10.06.2020
comment
По правильно? Я имею в виду первичный, если EJB и CDI могут работать вместе указанным образом. - person Alex Mi; 11.06.2020
comment
Вы говорите только о EJB без сохранения состояния, я считаю, что это может быть правильно, но вы можете использовать простой CDI для служб управления, но это неправильный путь, а только образец передовой практики. - person fantarama; 11.06.2020