0
votes

With JEE 5 / EJB 3.0 life of Java developers became much more easier. Later, influenced by Spring and CDI, similar approaches were also adopted in JEE. Now, I hope I am doing it right, but just to be sure: I have several Stateless EJBs, which all query and / or modify the database. An example is

@Stateless
public class AddressDBService {

    @PersistenceContext
    protected EntityManager em;

Some of the Stateless EJB refer the other services like this:

@Stateless
public class AVeDBService  {

@PersistenceContext
protected EntityManager em;

@Inject
private HomeToDealDBService homeToDealDBService;

@Inject
private AddressDBService addressDBservice;

and in the Stateless EJBs I have public methods like the ones below:

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

While I am almost certain this usage is correct and thread-safe (the above services are in turn injected into JSF Managed Beans). Could somebody confirm that my usage is correct, thread-safe and conforms good practices?

My usage seems to be conform with the following questions:

Is EntityManager really thread-safe?

Stateless EJB with more injected EJBs instances

1

1 Answers

1
votes

The "is correct?" question can't be answered without know the goal of the project. It could works? Yes, you have posted java-ee code that could deploy, but is not enough.

I usually use BCE (Boundary Control Entity) pattern and Domain Driven pattern. In this pattern we use EJB for business logic services or endpoint (JAX-RS) and all other injections, that are the Control part, are CDI objects.

Entities (JPA) could use cascade to avoid to manually save related entities:

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

can be avoided if you define the entity like this:

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

The @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) annotation usually respond to a specific transactions behavior, is not required, so is correct only if is what you want to do.