2

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

Community
  • 1
  • 1
Masood Ahmad
  • 731
  • 4
  • 15
  • 38

1 Answers1

11

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.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • +1 with Thanks, I got your point more than 90%. See edit -1 please for my cross questions. – Masood Ahmad Jun 25 '14 at 05:35
  • Definitely assume that I would always go with EJBs, so point 3 @ Traansactional is invalid here? I added 4 too. Lastly, by immutable I badly meant that those methods / actions that cant be further broken down. e.g `getUserById(id){return em.find(user.class, id);}` – Masood Ahmad Jun 25 '14 at 05:50
  • You should really read answers. As I said twice in my answer: *EJBs are transactional by default*. I also said: *Transactional was introduced to remove the need for EJBs and have transactional CDI beans*. Your point 4 doesn't make sense. If you don't use `@Stateless`, then you're not defining an EJB anymore. – JB Nizet Jun 25 '14 at 05:54
  • I read the answer and its a great answer. for point 4) There are other types of EJBs too. `@Stateless @Statefull , singleton` etc – Masood Ahmad Jun 25 '14 at 05:57
  • And they all are EJBs. And my answer says: *EJBs are transactional by default*. That's covered by basically every EJB tutorial (and by the spec). Read one. – JB Nizet Jun 25 '14 at 05:59
  • oh, I was meslead by the comment in your code. i thought stateless were the only case. `// stateless EJBs are transactional by defaults.` . Any ways. Thanks a lot : ) – Masood Ahmad Jun 25 '14 at 06:05