wsaxton
wsaxton

Reputation: 1082

How can I micromanage EJB transactions if EJB methods ignore the transaction attributes of other methods?

I have an EJB with 2 methods:

@Stateless
public FooFacade implements FooFacadeRemote {

    ...

    @TransactionAttribute(javax.ejb.TransactionAttributeType.NEVER)
    public void saveFoos(List<Foo> foos) {
        for(Foo foo: foos) {
            saveFoo(foo);
        }
    }

    @TransactionAttribute(javax.ejb.TransactionAttributeType.REQUIRED)
    private void saveFoo(Foo foo) {
        em.persist(foo);
    }
}

I just discovered that an EJB calling its own methods ignores the TransactionAttributeType of those methods. So I'm getting transaction required exceptions because saveFoo "sees" the TransactionAttributeType as NEVER.

I understand a workaround for this is to get another instance of the EJB to perform the task:

@EJB(name = "FooFacade")
private FooFacadeRemote self;

@TransactionAttribute(javax.ejb.TransactionAttributeType.NEVER)
public void saveFoos(List<Foo> foos) {
    for(Foo foo: foos) {
        self.saveFoo(foo);
    }
}

But is this really required? I mean, I don't want saveFoo to necessarily be exposed publicly.

Upvotes: 0

Views: 36

Answers (1)

Brett Kail
Brett Kail

Reputation: 33936

You don't need a separate EJB, you just need to call the method through the EJB proxy. If this is a stateless or singleton session bean, just an EJB reference to the same EJB:

@Stateless
public class MyEJB implements MyEJBInterface {
    @EJB MyEJBInterface self;
    ...

    @TransactionAttribute(javax.ejb.TransactionAttributeType.NEVER)
    public void saveFoos(List<Foo> foos) {
        for (Foo foo: foos) {
            self.saveFoo(foo);
        }
    }
}

If this is a stateful session bean, then inject @Resource SessionContext, and use getBusinessInterface to get an EJB proxy to the same stateful session bean instance.

Upvotes: 1

Related Questions