Jpa @manytone(fetch=FetchType.LAZY)延迟加载不工作

Jpa @manytone(fetch=FetchType.LAZY)延迟加载不工作,jpa,eclipselink,lazy-loading,Jpa,Eclipselink,Lazy Loading,我正在使用JPA2.1(EclipseLink 2.5.1)和JBoss7.1 我定义了非常简单的JPA实体: @Entity @Table(name="APLICACIONES_TB") public class Aplicacion implements Serializable { @Id @Column(name="COD_APLICACION_V") private long codAplicacionV; @Column(name="APLICACION_V")

我正在使用JPA2.1(EclipseLink 2.5.1)和JBoss7.1

我定义了非常简单的JPA实体:

@Entity
@Table(name="APLICACIONES_TB")
public class Aplicacion implements Serializable {

  @Id
  @Column(name="COD_APLICACION_V")
  private long codAplicacionV;

  @Column(name="APLICACION_V")
  private String aplicacionV;

  @OneToMany(mappedBy="aplicacion")
  private Collection<Prestacion> prestaciones;

  ... getters and setters
}

@Entity
@Table(name="PRESTACIONES_TB")
public class Prestacion implements Serializable {

  @Id
  @Column(name="COD_PRESTACIONES_V")
  private String codPrestacionesV;

  @Column(name="DESCRIPCION_V")
  private String descripcionV;

  @ManyToOne(fetch=FetchType.LAZY)
  @JoinColumn(name = "COD_APLICACION_V")    
  private Aplicacion aplicacion;

  ... getters and setters ...
}
因为我使用的是JSF 2.1,所以EJB被注入到托管bean中:

@ManagedBean(name = "ManagedBean")
@RequestScoped
public class ManagedBean
{   
  @EJB DocuEJB docuEjb;

  public String doSomething()
  {
     Prestacion entity = docuEjb.getResult("egesr");

     if (entity != null)
     {
        // It should return null because 'entity' should be detached
        Aplicacion app = entity.getAplicacion();

        // but 'app' entity is not null, ¿why not?
        System.out.println (app.getCodAplicacionV());
     }
  }
}
即使为“Prestacion”实体上的“aplicacion”字段定义了延迟加载,延迟加载也不起作用。之前发布的代码应在下一行返回NullPointerException:

System.out.println (app.getCodAplicacionV());
因为“应用程序”实体已分离,并且已配置延迟加载

为什么工作不是惰性加载


感谢您尝试在doSomething()上添加@Transactional,我认为您的事务管理器配置不好


您可以看到官方的spring文档。在任何情况下,您能否添加您的spring配置,以便我们能够更好地帮助您。:)

我不认为你遇到的行为异常,或者你的问题应该清楚地说明:

  • EJB默认是事务性的
  • 您的JSF使用
    @EJB
    注入一个EJB,我想JBoss可以创建一个java引用而不是代理
  • 由于事务未完成,实体正在被管理,它将在
    doSomething
    结束时完成
然后将您的实体加载到
EntityManager
,延迟加载可以工作,因为它有一个上下文


您将调用
em.execute(entity)
并获得结果,这可能会失败,因为该实体将不再被管理。

尝试添加@Transactional on doSomething()。如果在分离的对象中调用getAplicacion(),则应该会引发臭名昭著的LazyInitializationException异常。这不是。。。所以应用程序仍然被连接。@Xstian-我尝试了你建议的方法(事务性持久性上下文),但得到了相同的结果。@Ivan.aguirre-但是它不能被连接,因为我在ejb中使用事务性持久性上下文,所以当ejb方法完成时,持久性上下文是清晰的,所有实体都被分离。我在互联网上读到的所有JPA书籍中都读到过,即使在实体分离的情况下,惰性链接也可以与EclipseLink提供者一起工作。在这种情况下,EclipseLink只需从连接池中获取一个只读连接,执行加载,然后将连接放回连接池。我在下一个链接中读到了这一点:。但是我想在EclipseLink文档中找到这个解释。当你说@Transactional时,你是指@TransactionaAttribute(TransactionaAttribute.NOT_SUPPORTED)注释吗?doSomething是一种EJB方法。我的想法是,当您尝试获取关系时,事务已关闭。我建议你做一个像SpringTransaction这样的行为。我同意你的看法。但是如果你看一下我发布的代码,“doSomething”方法结束后,惰性引用将被解析。出于这个原因,它不应该解析惰性引用。例如,它在哪里被惰性加载而不应该被惰性加载?(因为您的示例指向的是
doSomething
,而不是您使用它的真实位置)。对不起,你说得对,我解释得不好。“getResult”方法是一个EJB方法,因为为EJB定义的持久性上下文类型是事务性的,所以应该分离“getResult”方法返回的实体。另一方面,“doSomething”方法是一个托管bean方法,我认为JEE容器不管理托管bean方法的事务;
System.out.println (app.getCodAplicacionV());