【问题标题】:Hibernate/JPA invocation of equals() triggers a lazy loading exception对 equals() 的 Hibernate/JPA 调用触发延迟加载异常
【发布时间】:2015-06-18 21:48:01
【问题描述】:

我已经按照older topic on stackoverflow 中的建议实现了 equals()/hashCode() 方法。这种方法的问题是例外

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() 之前抛出。它只发生在实体具有例如其他实体的外键。由于会话关闭(equals() 在新的 JSF 请求中调用,EntityManager 是请求范围的),Hibernate 尝试获取这些实体并触发异常。

解决方案的人从来没有遇到过这个问题,这就是我向你寻求帮助的原因。

编辑 14.04.2015 14:50: equals() 都是使用实体的 ID 实现的。但是对于这个例子,我已经用一个简单的 return 替换了它的实现,因为这并不重要。我发现在外部实体 (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
    }
}

【问题讨论】:

    标签: hibernate jpa


    【解决方案1】:

    希望我能够理解您的问题。

    要么避免延迟加载,要么强制在同一查询触发期间获取结果,要么修改你的 equals 和 hashcode 方法

    希望这些帮助(建议在外键关系的情况下编写方法); Should I write equals() methods in JPA entities? https://developer.jboss.org/wiki/EqualsandHashCode?_sscc=t

    【讨论】:

    • @MasterSlave 问题是,根本没有输入 equals() 方法。在真正访问我的方法实现之前,Hibernate 会引发异常。我可以将其更改为返回任何固定值,但它仍然会引发异常。我会延长我最初的帖子,给你一个更好的例子。
    【解决方案2】:

    为了补充@Godwin 的答案,我将更改equalshashCode,以便它们在对象附加到持久上下文以及分离时都是可靠的。这意味着您应该避免任何关联的对象或自动生成的 Id。 @Godwin 提供的链接解释了这一切,它的总结是你应该尝试找到一个自然键,(例如,用户实体中的电子邮件等)

    您不应该做的一件事是更改为 EAGER 加载,因为有一个众所周知的休眠 bug,其中在填充字段值之前触发 hashCode 导致更大的混乱

    【讨论】:

      猜你喜欢
      • 2012-05-21
      • 1970-01-01
      • 2016-12-21
      • 1970-01-01
      • 2011-07-29
      • 2019-04-28
      • 2011-05-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多