在类层次结构中使用注入的 EntityManager
以下代码有效:
@Stateless
@LocalBean
public class MyClass
{
@PersistenceContext(name = "MyPU")
EntityManager em;
public void myBusinessMethod(MyEntity e)
{
em.persist(e);
}
}
但以下层次结构在 Glassfish 3.0(以及带有 EclipseLink 的标准 JPA 注释)中的 persist
行处给出了 TransactionRequiredException。
@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);
}
}
对于我的 EJB,我在抽象类中收集了通用代码,以获得更清晰的代码。 (update
还保存了谁执行了操作以及何时执行的操作,我的所有实体都实现了一个接口。)
这个问题并不致命,我可以简单地将 update
和姊妹方法复制到子类中,但是我想将它们全部放在一个地方。
我没有尝试,但这可能是因为我的基类是抽象的,但我想为这种(恕我直言,常见)用例学习正确的方法。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
AFAIK,您无法注入到超类中,因此您必须注入到实际 EJB 的字段或方法中。你可以这样做:更新:我错了,根据Java EE 5平台规范的第5.2.3节,注入是允许的超类字段和方法。
我更进一步,使用类似的代码 GlassFish v3 和 EclipseLink 做了一个小测试,但我无法重现您的问题。所以我怀疑您的
persistence.xml
存在某种问题。你能提供一下吗?您使用的是transaction-type="JTA"
吗?为了以防万一,这是我使用的:顺便说一句,我认为跳过 DAO 模式来进行简单的数据访问操作是完全可以的。看看之前的答案。
AFAIK, you can't inject into a super class, so you have to inject into a field or method of the actual EJB. You could do something like this:Update: I was wrong, according to the section 5.2.3 of the Java EE 5 platform specification, injection is allowed in super class fields and methods.
I went a bit further and did a small test on my side using similar code, GlassFish v3 and EclipseLink and I can't reproduce your problem. So I suspect some kind of problem with your
persistence.xml
. Could you provide it? Are you using atransaction-type="JTA"
? Just in case, here is the one I used:BTW, I think that it's perfectly fine to skip the DAO pattern for simple data access operations. Have a look at this previous answer.
您的方法没有错误(如果有效)
,但是更常见的是使用(注入)Dao 并在其上调用方法,或者如果 Dao 是仅包装 EntityManager 的冗余层,您可以直接调用 EntityManager 上的方法。当然,通过受保护的 getter 将 EntityManager 暴露给子类。
Your approach isn't wrong (if it works)
However it is more common to either use (inject) a Dao and call methods on it, or if the Dao is a redundant layer that only wraps the
EntityManager
, you can simply call the methods onEntityManager
directly. Of course, exposing theEntityManager
to subclasses via a protected getter.问题不在于使用超类的注入实体管理器,而是调用另一个 EJB 的方法:例如,
当
OtherBean
不是 bean 并且checkAuthority
是一个静态方法时,我使用了此模式(非 JTA)EntityManagerFactory
。然后我也更改了OtherBean
来扩展MySuperBean
。我想,在这种情况下,当OtherBean
结束checkAuthority
时,JTA结束事务,MySuperBean
的insert
可以找不到事务来持久化实体。可以理解的是,无状态 EJB 不允许其他 EJB 继续进行事务。作为 Pascal,我最初认为注入不适用于继承,但是当我在子类中直接调用
em.persist()
时,这个问题仍然存在。之后我终于能够检查其他可能的原因。感谢您的所有意见。
The problem was not using superclass' injected entity manager, but calling another EJB's method: e.g.
I was using this pattern when
OtherBean
was not a bean andcheckAuthority
was a static method using (non-JTA)EntityManagerFactory
. Then I changedOtherBean
to extendMySuperBean
too. I think, in this case, whenOtherBean
endscheckAuthority
, JTA ends the transaction andMySuperBean
'sinsert
can'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.