4

I am experimenting with CDI on a test application. I have a DAO which injects a container managed JTA persistence context like this:

public class TestDAO implements Serializable {
    @PersistenceContext
    private EntityManager entityManager;

    public void insertEntity(Test test) {
        entityManager.persist(test);
    }
}

Now I have a CDI controller bean like this:

@Named
@SessionScoped
public class TestController implements Serializable {
    @Inject
    private TestDAO testDAO;

    public void finishGame() {
        testDAO.insertEntity(new Test(1, 2, 3));
    }
}

If I run this, I receive an error in the DAO when trying to insert the entity, because there is no active transaction available. So far so good. I can solve this by making the controller bean a stateful EJB which will wrap the finishGame() in a transaction.

But let assume I don't want an EJB. As a test I annotated the finishGame() with the @TransactionAttribute annotation and it worked(the controller bean is NOT an EJB). So my question is: how does it work? Does the CDI define @TransactionAttribute for plain beans? I know that Seam Persistence Module does this, but I am not using it. Actually I added it to the project, but I removed it after, because I received awkward exceptions.

Could anyone clear my confusion? Do really CDI define @TransactionAttribute for plain beans?

P.S. I have another sort of question. I see the tendencies is to port all EJB annotations to plain beans. So will EJBs become obsolete in the future? I mean I saw in JIRA that @TransactionAttribute will be added in the future for plain beans(the task is still not resolved). So isn't this eclipsing EJBs, sort of duplicating functionality?

Best regards, Petar

Petar Minchev
  • 46,889
  • 11
  • 103
  • 119

1 Answers1

3

You need do define a transaction interceptor. Basically define a @Transactional annotation and intercept all methods annotated with it. In the interceptor just begin, commit or rollback the transaction. It gets more complicated when transaction propagation comes into the picture. So check if Seam doesn't have anything ready-to-use http://seamframework.org/Seam3/PersistenceModule

Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
  • 1
    +1, thanks for the useful answer! But my question is why `@TransactionAttribute` worked on a plain `CDI` bean, without doing anything? I have always thought that `@TransactionAttribute` works only for `EJBs`. – Petar Minchev Aug 03 '11 at 11:23
  • yes, I think it's the case - @TransactionAttribute should not work out-of-the box – Bozho Aug 03 '11 at 11:28
  • 1
    Yeah and that's the strange thing. When you have enough time, could you just make a simple `CDI` application and try if the `@TransactionAttribute` works on a plain `CDI` bean. It is driving me crazy because I know it shouldn't work on a plain bean... – Petar Minchev Aug 03 '11 at 12:45
  • I will also make again a sample application from scratch to confirm if I am missing something, which is the most probable case:) – Petar Minchev Aug 03 '11 at 12:46
  • http://www.theserverside.com/tip/Dependency-Injection-in-Java-EE-6-Part-6 this here tells what I thought - if there is seam, it can plug-in CDI and allow @TransactionAttribute to be resolved. But not with plain CDI. – Bozho Aug 03 '11 at 12:50
  • Thanks for the link, maybe the appication server has cached something. Because I added `Seam Persistence` at first to the project and then I removed it. I will try it again tonight. – Petar Minchev Aug 03 '11 at 12:51
  • 2
    This was the case. `Glassfish` has cached the libraries and descriptors, although I told `NetBeans` to clean the build. Now it throws a transaction required exception as it should be. Thanks for helping:) – Petar Minchev Aug 03 '11 at 16:04