【问题标题】:JSF + Hyperjaxb3 + Hibernate LazyInitializationException accross requestsJSF + Hyperjaxb3 + Hibernate LazyInitializationException 跨请求
【发布时间】:2010-09-24 13:47:36
【问题描述】:

我有 JSF 应用程序,其中包含由 Hyperjaxb3 生成的 trinidad 组件和 JAXB/JPA 实体 bean。在 UI 中,我使用以 JPA 对象为值的 Trinidad 组合框组件。

场景是:

  1. 用户在组合框中进行选择
  2. 用户单击向服务器发送请求并返回到相同表单的控件
  3. 表单中的数据已提交,组合框中的选择应与用户在步骤 1 中所做的一样。对组合框项(JPA 对象)调用 equals() 方法并引发此异常:

org.hibernate.LazyInitializationException: 延迟初始化角色集合失败:package.AnObject.items,没有会话或会话被关闭 在 org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:358) 在 org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:350)

 at org.hibernate.collection.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:97)

 at org.hibernate.collection.PersistentBag.size(PersistentBag.java:225)

 at org.jvnet.hyperjaxb3.item.AbstractItemList.size(AbstractItemList.java:51)

 at java.util.AbstractList$Itr.hasNext(Unknown Source)

 at org.jvnet.jaxb2_commons.lang.builder.JAXBEqualsBuilder.append(JAXBEqualsBuilder.java:57)

 at org.jvnet.jaxb2_commons.lang.builder.JAXBEqualsBuilder.append(JAXBEqualsBuilder.java:29)

 at package.AnObject.equals(AnObject.java:177)

 at org.jvnet.jaxb2_commons.lang.builder.JAXBEqualsBuilder.append(JAXBEqualsBuilder.java:34)

 at package.ParentObject.equals(ParentObject.java:532)

 at package.ParentObject.equals(ParentObject.java:551)

 at java.util.ArrayList.indexOf(Unknown Source)

 at org.apache.myfaces.trinidad.component.UIXSelectMany._destructiveCompareOutOfOrderLists(UIXSelectMany.java:179)

 at org.apache.myfaces.trinidad.component.UIXSelectMany.compareValues(UIXSelectMany.java:139)

 at org.apache.myfaces.trinidad.component.UIXEditableValue.validate(UIXEditableValue.java:180)

 at org.apache.myfaces.trinidad.component.UIXEditableValue._executeValidate(UIXEditableValue.java:503)

 at org.apache.myfaces.trinidad.component.UIXEditableValue.processValidators(UIXEditableValue.java:270)

 at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1058)

 at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1058)

我使用 Spring 中的 OpenEntityManagerInViewFilter 来获取延迟加载的对象 - 在一个请求中工作。

在 HyperJAXB 生成的对象级别上,equals() 方法调用 equals(Object object, EqualsBuilder equalsBuilder) 方法,其中在该对象的每个属性上调用 equalsBuilder.append(...)。当该属性是一个列表时,它由 PersistenBag 代理,这就是我得到 LazyInitializationException 的地方。

equals() 方法 - 由 HyperJaxb 生成:

public boolean equals(Object object) {
    if (!(object instanceof ParentObject)) {
        return false;
    }
    if (this == object) {
        return true;
    }
    final EqualsBuilder equalsBuilder = new JAXBEqualsBuilder();
    equals(object, equalsBuilder);
    return equalsBuilder.isEquals();
}

equals(Object object, EqualsBuilder equalsBuilder) 由 HyperJaxb 生成:

public void equals(Object object, EqualsBuilder equalsBuilder) {
    if (!(object instanceof ParentObject)) {
        equalsBuilder.appendSuper(false);
        return ;
    }
    if (this == object) {
        return ;
    }
    final ParentObjectthat = ((ParentObject) object);
    // PersitentBag, LazyInitializationException is thrown here
    equalsBuilder.append(this.getAnObject(), that.getAnObject());
    equalsBuilder.append(this.get..., that.get...);
    ...
}

你们有什么想法可以解决这个问题吗?

我尝试使用 JSF 转换器并让 SelectItem 带有一个 String 值(不是对象),但如果我记得在 String 转换为我的对象后调用 equals()。

【问题讨论】:

    标签: hibernate jpa lazy-loading trinidad hyperjaxb


    【解决方案1】:

    你得到这个是因为你的对象没有被分离 (1) 并且你在会话之外访问数据 (2) (3)。要更正,您应该以任意组合地址 (1-3)。

    1. 分离您的对象。这可能是最简单的,但它不是延迟加载。
    2. 确保会话可用。您说您正在使用 OEMIV 模式 - 当调用 equals 方法时,为什么会话不存在?我相信这是因为 equals 不是在视图渲染期间而是在其他一些 JSF 阶段调用的。您可以尝试扩展 OEMIV 模式,使其跨越整个 JSF 生命周期。
    3. 不要访问数据。建议使用 equals(...) 和 hashCode(...) 方法,但不是必需的。您可以在 HJ3 中禁用它们的生成,您可以从 hashCode()/equals(...) 构建中排除某些属性,您可以使用自己的 equals 和 hashCode 策略 - 有很多方法可以实现这一点。

    我个人,我会先检查一下,为什么会话不存在。

    【讨论】:

    • ps。随时将您的问题发布到 users@hyperjaxb.dev.java.net。
    • 感谢 Lexi 的命中。最后,我设法找到了问题 - OpenEntityManagerInViewFilter 必须设置为第一个过滤器(不知道为什么),但现在似乎都在会话中,没有 Lazy Init 异常
    猜你喜欢
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 2011-12-21
    • 1970-01-01
    • 2017-02-23
    • 2012-11-19
    相关资源
    最近更新 更多