Jpa @manytone(fetch=FetchType.LAZY)延迟加载不工作
我正在使用JPA2.1(EclipseLink 2.5.1)和JBoss7.1 我定义了非常简单的JPA实体: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")
@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,我想JBoss可以创建一个java引用而不是代理@EJB
- 由于事务未完成,实体正在被管理,它将在
结束时完成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());