java - 在类层次结构中使用注入(inject)的 EntityManager

标签 java jpa jakarta-ee ejb-3.0 jta

以下代码有效:

@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,我在一个抽象类中收集了公共(public)代码,以获得更清晰的代码。 (update 还保存了操作的执行者和时间,我所有的实体都实现了一个接口(interface)。)

这个问题不是致命的,我可以简单地将 update 和姊妹方法复制到子类,但我想将它们全部放在一个地方。

我没有尝试,但这可能是因为我的基类是抽象的,但我想为这种(恕我直言,常见)用例学习一种合适的方法。

最佳答案

据我所知,您不能注入(inject)父类(super class),因此您必须注入(inject)实际 EJB 的字段或方法。你可以这样做:

public class MyBaseEJB {
   public abstract EntityManager getEM();

   public void update(Object e) {
       getEM().persist(e);
   }

}

@Stateless
public class MyEJB extends MyBaseEJB {
   @PersistenceContext
   EntityManager em;

   public EntityManager getEM() { return em;}
} 

<罢工>

更新:我错了,根据 Java EE 5 平台规范的第 5.2.3 节,允许在父类(super class)字段和方法中注入(inject)。

我更进一步,使用类似的代码 GlassFish v3 和 EclipseLink 在我这边做了一个小测试,但我无法重现您的问题。所以我怀疑你的 persistence.xml 有问题.你能提供吗?您使用的是 transaction-type="JTA" 吗? ?为了以防万一,这是我使用的:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence persistence_2_0.xsd" version="2.0">
  <persistence-unit name="MyPU" transaction-type="JTA">
    <!-- EclipseLink -->
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <jta-data-source>jdbc/q2484443</jta-data-source>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties>
      <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
      <property name="eclipselink.ddl-generation.output-mode" value="database"/>
    </properties>
  </persistence-unit>
</persistence>

顺便说一句,我认为对于简单的数据访问操作跳过 DAO 模式是非常好的。看看this previous answer .

关于java - 在类层次结构中使用注入(inject)的 EntityManager,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2484352/

相关文章:

Java Spring Security - User.withDefaultPasswordEncoder() 已弃用?

java - 如何使用 Unity3D 将变量从 AndroidJavaObject 获取到 C# 类中

java - Maven:覆盖父pom以将映射添加到 'rpm-maven-plugin'

java - JPA JoinTable 与过滤列的 OneToMany 关系

java - weblogic 10.3 上的 ClassCastException jboss-seam

java - 客户端是否一直连接到消息队列中的消息调度程序?

java - 2D JRadioButton 对象数组

hibernate - Play Framework 2.4 中的 Play Evolutions 和 JPA

java - 使用 JPA 映射计算属性

java - 带有 websphere 的 jBPM