Hibernate/JPA调用equals()会触发延迟加载异常
我已经实现了equals()/hashCode()方法,正如在一个示例中所建议的那样。这种方法的问题是个例外Hibernate/JPA调用equals()会触发延迟加载异常,hibernate,jpa,Hibernate,Jpa,我已经实现了equals()/hashCode()方法,正如在一个示例中所建议的那样。这种方法的问题是个例外 org.hibernate.LazyInitializationException: could not initialize proxy - no Session at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:160) [hibernate-core-
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:160) [hibernate-core-4.1.6.Final.jar:4.1.6.Final]
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:259) [hibernate-core-4.1.6.Final.jar:4.1.6.Final]
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185) [hibernate-core-4.1.6.Final.jar:4.1.6.Final]
at pkg.db.TblChain_$$_javassist_815.equals(TblChain_$$_javassist_815.java) [classes:]
[...]
在调用equals()之前抛出。仅当实体具有其他实体的外键时才会发生这种情况。Hibernate尝试获取这些实体并触发异常,因为关闭了会话(equals()在新的JSF请求中被调用,EntityManager在请求范围内)
解决方案的人从来没有碰到过那个问题这就是为什么我要请你帮忙
编辑14.04.2015 14:50:
两个equals()都是使用实体的ID实现的。但是对于这个例子,我用一个简单的返回代替了它的实现,因为这无关紧要。我发现,如果我在外国实体(tblChain)中有另一个外国实体(如tblChainType),这并不重要。如果在用于加载的实体管理器处于活动状态时未使用第一个实体管理器,则它将始终失败
// Entity classes
public class TblChainInstance {
private TblChain tblChain; // Foreign entity
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "intChainId", nullable = false)
public TblChain getTblChain() {
return this.tblChain;
}
public boolean equals(Object other) {
return false; // doesn't matter, what I have here.
// It always works if this is the selected Entity.
}
}
public class TblChain {
public boolean equals(Object other) {
return false; // doesn't matter, what I have here.
// It always throws a LazyInitializationException
}
}
// Testcode
@Named @ViewScoped
public class MyBean implements Serializable {
private TblChainInstance _tblChainInstance;
@PostConstruct
public void _init() {
_tblChainInstance = new JPAQuery(_entityManager).from(qtChainInstance)
.limit(1).singleResult(qtChainInstance);
}
public void actionListener() {
System.out.println(_tblChainInstance.equals(1)); // outputs false
System.out.println(_tblChainInstance.getTblChain().equals(1)); // throws
}
}
希望我能理解你的问题 要么避免延迟加载,使其成为强制加载,这将在同一查询触发期间获取结果,要么修改equals和hashcode方法 希望这些帮助(外键关系情况下的写作方法建议);
为了补充@Godwin的答案,我将更改
等于
和hashCode
,这样它们在对象附加到持久上下文的情况下以及在对象分离时都是可靠的。这意味着您应该避免使用任何关联对象或自动生成的Id。@Godwin提供的链接解释了这一切,其摘要是您应该尝试查找自然密钥(例如,用户实体中的电子邮件等)
有一件事你不应该因为这个原因而改变为急切加载,因为有一个众所周知的hibernate,在填充字段值之前触发hashCode,导致更大的混乱@MasterSlave问题是,根本没有输入equals()方法。Hibernate在我的方法实现真正被访问之前抛出异常。我可以将其更改为返回任何固定值,它仍然抛出异常。我会延长我最初的帖子,给你一个更好的例子。