Search code examples
springjakarta-eespring-mvcjava-ee-6java-ee-7

Service layer and dao layer in java ee EJBs


Question: Can anyone, in context to Java EE and EJBs, show a specific DAO class (or more than one) that has two different methods. and a service class that calls those 2 methods in ONE transactional boundary with roll back?

I have an EJB but I want to use it as service layer like in spring @Transactional methods.

1) is it a good idea ?

2) how can I make many dao method calls in one "transaction" in one method? I think I have to make some strategy on transaction.begin() and . comit()? can anyone show a code example please?

Some of the main advantages would be that:

a- all the small immutable DAO transactions will be committed in "one go" in the single database connection made (in single transactional boundries)

b- If say I have 4 dao calls in server and the third one fails, since its one transactional boundry, I can do roll backs.

c- my immutable DAO methods will be re-usable in many other places.

Java EE example:

import com.....entities.Users;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

@Stateless
public class UsersBean {

    // Add business logic below. (Right-click in editor and choose
    // "Insert Code > Add Business Method")

    public Users sayHello() {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("CommunityPU");
        EntityManager em = emf.createEntityManager();
        Users user =  em.find(Users.class, 1);
        em.close();
        emf.close();
        return user;
    }

}

vs. spring:

@Controller
class MyControllerClass {

      @RequestMapping...
      method(){
         ServiceCall()...
      //put something to modelAndView object here and redirect to jsp page.
      return "home"; // this will redirect data to home.jsp

      }
}

//Service class /////////

@Service
class MyServiceClass{
      @Transactional
      SomeServiceMethod(){ 
        DaoMethod(); 
        SomeMoreDaoMethods();
      }

}

//Dao class ////////

@Autowired
EntityManager em;

@Repository
class MyDaoClass{
   DaoMethdon(){em.find(...)}

}

/view/myjsps.jsp  path to view directory set in spring.xml

Edit - 1 (cross question to the answer for further clarification)


1) will the DAO itself be an EJB? or EJBs are strict service layers that call other immutable dao methods (that reside in dao classes).

2) we wont use entitymanager in EJBs but in Daos. correct?

3) how about using @Transactional (Until Java EE 7 only EJB where transactional and the @Transactional annotation didn't exist.) or @TransactionAttribute.

4) what if we use non @stateless. Then it wont manage the daos in one transactional boundry not use roll backs?

RND links:

https://stackoverflow.com/a/17840851

http://docs.oracle.com/javaee/5/tutorial/doc/bncij.html


Solution

  • Is is a good idea?

    Yes. That's what EJBs are for, basically.

    how can I make many dao method calls in one "transaction" in one method?

    You just do it:

     @Stateless
     public class MyService {
    
         @Inject
         private FirstDao firstDao;
    
         @Inject
         private SecondDao secondDao;
    
         // stateless EJBs are transactional by defaults.
         public void doStuff() {
             firstDao.doSomething();
             secondDao.doSomethingElse();
         }
    }
    

    EJBs are transactional by default. You don't need to start and commit transactions programmatically. The container does that for you: if any of the 2 DAO calls throws a runtime exception, the transaction will roll back. Otherwise, it will commit.

    Also note that the entity manager shouldn't be used by your service EJB. That's what DAOs are for: deal with persistence. So the DAOs should be the one using the entity manager:

    public class FirstDao {
        @PersistenceContext
        private EntityManager em;
    
        ...
    }
    

    Regarding your last questions:

    1. DAOs can be EJBs themselves, but it's not necessary, since transactions are normally demarcated by the service layer.
    2. I already answered that. Of course The Data access objects are the ones who must use the EntityManager, since their job is to handle persistence, and the EntityManager is used to access the database.
    3. Do it the way you want. What's important is that your services should be transactional, whatever the way you make them transactional. Transactional was introduced to remove the need for EJBs and have transactional CDI beans. If you prefer it that way, then fine.

    Small note: an immutable method doesn't make sense. Something (like an object) is immutable when its state never changes. Methods don't have state.