0
votes

Let's suppose I have a simple lib named db-utils, which has a CrudService CDI bean (requestScoped) that's used by my web applications to perform CRUD operations.

I also have an EJB project named grad-db, which has the entities mapped from database. Grad-db also has the producer used to set the entityManager in db-utils' CrudService.

I already tried it and apparently it works fine. My question is: is that a bad practice? Is there any consequence of producing a CDI bean inside a stateless session bean and passing the EJB stateless bean as a parameter to the CrudService?

My code:

EJB Bean (grad-db):

@Stateless
public class CrudServiceCae extends AbstractCrud implements Serializable {
    private static final long serialVersionUID = 1L;

    @PersistenceContext(unitName = "cae-pu")
    EntityManager em;

    @Override
    public EntityManager getEntityManager() {
        return em;
    }

    @Produces
    @Database(Schema.CAE)
    public CrudService createCrudServiceCou() {
        return new CrudService(this);
    }
}

CrudService (db-utils):

@Named("crudService")
public class CrudService implements Serializable {

    private static final long serialVersionUID = -2607003150201349553L;

    private AbstractCrud crud;

    public CrudService(AbstractCrud abstractCrud) {
        this.crud = abstractCrud;
    }

    ...
}

Edit: Actually it worked only for queries. When I tried to insert data I got javax.persistence.TransactionRequiredException. Apparently I'm going to have to use inheritance instead of CDI in this case.

1

1 Answers

1
votes

The EJBs are responsable for business processes/logic (i.e: methods), and are able to orchestrating others CDI controllers, is not so common let the EJB create objects, for that you would prefer a CDI POJO Producer.

In your case is leaner to use a CDI object and produce the object that you need from there, looks like a DAO and could be used (i mean, injected) into the EJB.

Think of EJBs on terms of a Boundary Pattern, using specialized controllers.

Notes:

  • @Stateless is not required to implements Serializable, these are pooled, and its lifecycle does not allow serialization.
  • In general you dont want to use a getter to the entity manager of an EJB, you should prefer write a method and use the em internally.
  • The persistence context is easier to manipulate if uses JTA
  • Your @Stateless should begins the transactions and let them propagated along the controllers
  • The em with package visibility is a good idea, lets you mock your facade / boundary easily