I have a stateless bean something like:
@Stateless
public class MyStatelessBean implements MyStatelessLocal, MyStatelessRemote {
@PersistenceContext(unit
Matt, the question you ask is a pretty classic one, I think the self-reference solution by Herval/Pascal is neat. There is a more general solution not mentioned here.
This is a case for EJB "user" transactions. Since you are in a session bean you can get the user transaction from the session context. Here's how your code will look with user transactions:
// supposing processObjects defined on MyStatelessRemote1 and process defined on MyStatelessLocal1
@Stateless
@TransationAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class MyStatelessBean1 implements MyStatelessLocal1, MyStatelessRemote1 {
@Resource
private SessionContext ctx;
@EJB
private MyStatelessLocal1 myBean2;
public void processObjects(List<Object> objs) {
// this method just processes the data; no need for a transaction
for(Object obj : objs) {
this.myBean2.process(obj);
}
}
public void process(Object obj) {
UserTransaction tx = ctx.getUserTransaction();
tx.begin();
// do some work with obj that must be in the scope of a transaction
this.mgr.merge(obj);
// ...
this.mgr.merge(obj);
// ...
this.mgr.flush();
tx.commit();
}
}
I think has to do with the @TransationAttribute(TransactionAttributeType.Never) on method processObjects.
TransactionAttributeType.Never
http://docs.sun.com/app/docs/doc/819-3669/6n5sg7cm3?a=view
If the client is running within a transaction and invokes the enterprise bean’s method, the container throws a RemoteException. If the client is not associated with a transaction, the container does not start a new transaction before running the method.
I assume that you are client the method processObjects from the client code. Because probably your client is not associated with a transaction the method call with TransactionAttributeType.Never is happy in the first place. Then you call the process method from processObjects that altough having the TransactionAttributeType.Required annotation was not a bean method call and the transaction policy is not enforced. When you call merge you get the exception because you are still not associated with a transaction.
Try using TransactionAttributeType.Required for both bean methods to see if it does the trick.