ejbmanaged-beanstateful-session-bean

RequestedScopre ManagedBean VS Stateful Bean


How to choose which implementation of UserDao class? One is a stateful session EJB, and the other one is a manged session bean with RequestedScope annotation.

The code of the stateful session seems much simpler. In this user greeter case, both should work?

Also, what's the scope of a stateful EJB?

UserDao.java

public interface UserDao {
    User getForUsername(String username);

    void createUser(User user);
 }

EJBUserDao.java

@Stateful
@Alternative
public class EJBUserDao implements UserDao {

@Inject
private EntityManager entityManager;

public User getForUsername(String username) {
    try {
        Query query = entityManager.createQuery("select u from User u where u.username = ?");
        query.setParameter(1, username);
        return (User) query.getSingleResult();
    } catch (NoResultException e) {
        return null;
    }
}

public void createUser(User user) {
    entityManager.persist(user);
}
}

ManagedBeanUserDao.java

public class ManagedBeanUserDao implements UserDao {

@Inject
private EntityManager entityManager;

@Inject
private UserTransaction utx;

public User getForUsername(String username) {
    try {
        User user;
        try {
            utx.begin();
            Query query = entityManager.createQuery("select u from User u where u.username = :username");
            query.setParameter("username", username);
            user = (User) query.getSingleResult();
        } catch (NoResultException e) {
            user = null;
        }
        utx.commit();
        return user;
    } catch (Exception e) {
        try {
            utx.rollback();
        } catch (SystemException se) {
            throw new RuntimeException(se);
        }
        throw new RuntimeException(e);
    }
}

public void createUser(User user) {
    try {
        try {
            utx.begin();
            entityManager.persist(user);
        } finally {
            utx.commit();
        }
    } catch (Exception e) {
        try {
            utx.rollback();
        } catch (SystemException se) {
            throw new RuntimeException(se);
        }
        throw new RuntimeException(e);
    }
}
}

Solution

  • The EJB is simpler just because of using UserTransaction in the other bean, nowadays with CDI 1.1 you can do the same in CDI as in your EJB (just annotate the bean or methods with TransactionAttribute.REQUIRED).

    However you shouldn't mark your DAO bean as Stateful or SessionScoped, DAO is a stateless service by nature so you are probably looking for Stateless or RequestScoped. I would go with plain CDI (if you don't need other EJB features like async calls), it's getting more and more stuff from EJB (for instance transactions) and I guess that those two technologies will get merged eventually.