Syd
Syd

Reputation: 185

EJB Transaction attribute overriding in method-level

I have a CDI conversation scoped action class which I am also making a stateful EJB for holding state of objects throughout the conversation life cycle.

As the action class is an EJB, so by default all methods will be transactional, which I intentionally don't want to do. I just want a single method of the action class will be transactional where I will only perform database persistence tasks. So I annotate that single method with @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW). And the action class is annotated with @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED).

When I call the transactional method from other handler methods of the same action class, there no transaction starts.

Here is the code sample.

@Stateful
@Named
@ConversationScoped
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class MyAction implements Serializable {

    @PersistenceContext(type = PersistenceContextType.EXTENDED)
    private EntityManager em;
    ........
    ........
    ........

    public String handlerMethod1() {
        // do some staffs.
        persist();
        return "view";
    }

    public String handlerMethod2() {
        // do some staffs.
        persist();
    }

    .......
    .......
    .......

    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    private void persist() {
        // save objects.
        em.flush();
    }
}

No transaction starts when invoked persist() method though I have annotated it with @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW), but why?

Please help me getting rid of this.

Upvotes: 3

Views: 2519

Answers (1)

Gabriel Aramburu
Gabriel Aramburu

Reputation: 2981

You have two problems here:

a) persist() is not a business method. A Business method have to be (among other rules) public.

b) you are calling the persist() method with a simple object method invocation, therefore, the Container is not able to manage the code. Remember that @TransactionAttribute annotation needs to be interpreted by the Container, which doesn't occurs in this case.

One possible solution could be to create other EJB with the persist() method code and inject him in MyAction bean. This way, every time you invoke the persist() method, the Container will intercept the call and it will create a new transaction.

Upvotes: 4

Related Questions