The following code works:
@Stateless
@LocalBean
public class MyClass
{
@PersistenceContext(name = "MyPU")
EntityManager em;
public void myBusinessMethod(MyEntity e)
{
em.persist(e);
}
}
But the following hierarchy gives a TransactionRequiredException in Glassfish 3.0 (and standard JPA annotations with EclipseLink.) at the line of persist.
@Stateless
@LocalBean
public class MyClass extends MyBaseClass
{
public void myBusinessMethod(MyEntity e)
{
super.update(e);
}
}
public abstract class MyBaseClass
{
@PersistenceContext(name = "MyPU")
EntityManager em;
public void update(Object e)
{
em.persist(e);
}
}
For my EJB’s I collected common code in an abstract class for cleaner code. (update also saves who did the operation and when, all my entities implement an interface.)
This problem is not fatal, I can simply copy update and sister methods to subclasses but I would like to keep all of them together in a single place.
I didn’t try but this may be because my base class is abstract, but I would like to learn a proper method for such a (IMHO common) use case.
The problem was not using superclass’ injected entity manager, but calling another EJB’s method: e.g.
I was using this pattern when
OtherBeanwas not a bean andcheckAuthoritywas a static method using (non-JTA)EntityManagerFactory. Then I changedOtherBeanto extendMySuperBeantoo. I think, in this case, whenOtherBeanendscheckAuthority, JTA ends the transaction andMySuperBean‘sinsertcan’t find a transaction to persist entity. Understandably Stateless EJB’s don’t let fellow EJB’s to proceed the transaction.As Pascal, I initially thought that injection does not work with inheritance but this problem continued when I directly called
em.persist()in the subclass. After this I finally was able to check other possible causes.Thanks for all the input.