@ManyToOne(fetch = FetchType.LAZY)延迟加载不起作用

时间:2014-09-02 14:53:51

标签: jpa eclipselink lazy-loading

我正在使用JPA 2.1(EclipseLink 2.5.1)和JBoss 7.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 ...
}

我开发了一个staless EJB,它执行查询以获得一些&#34; Aplicacion&#34;实体。

@Stateless
@LocalBean
public class DocuEJB implements DocuEJBLocal
{
  @PersistenceContext(name="DocuEjb", type=PersistenceContextType.TRANSACTION)
  private EntityManager em;

  public Prestacion getResult(String name)
  {
    return em.createNamedQuery("ExampleQueryName", Prestacion.class).getSingleResult();
  }
}

因为我正在使用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());
     }
  }
}

即使为“aplicacion”定义了延迟加载,延迟加载也无法正常工作。 &#39; Prestacion&#39;实体。之前发布的代码应该在下一行返回NullPointerException:

System.out.println (app.getCodAplicacionV());

因为&#39; app&#39;实体已分离,并且已配置延迟加载。

为什么不进行延迟加载?

由于

2 个答案:

答案 0 :(得分:0)

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

您可以看到here官方春季文档。在任何情况下,您都可以添加弹簧配置,以便我们更好地为您提供帮助。 :)

答案 1 :(得分:0)

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

  • EJB默认为transactional
  • 你的JSF用@EJB注入一个EJB,我想JBoss可以创建一个java引用而不是代理
  • 正在管理实体,因为交易未完成,它将在doSomething结束时完成。

然后将您的实体加载到EntityManager,并且延迟加载有效,因为它有一个上下文。

您可以使用您获得的结果调用em.evict(entity),这可能会失败,因为实体将不再受管理。