【问题标题】:LazyInitializationException when entity pass to processor from reader当实体从读取器传递到处理器时出现 LazyInitializationException
【发布时间】:2018-01-29 15:19:44
【问题描述】:

我在 Wildfly 9.0.1 中使用 java 批处理 (jsr-352)。对实体的惰性字段进行步进(基于块)访问的处理器。当处理器想要获取惰性字段时,我给LazyInitializationException。当我在 wildfly 11.0.0.Alpha1 上运行它时,一切正常。 在 wildfly 9.0.1 中,当我使用存储库获取此字段时,没有问题。我怎样才能使用存储库做到这一点?

读者:

public Object readItem() {
   return answerRepository.findBy(23);
}

处理器:

public Object processItem(Object item) {
   AnswerEntitiy answerEntitiy = (AnswerEntitiy)item;
   //when i call answerEntitiy.getComment() LazyInitializationException throws
   return commentRepository.findByAnswer(answerEntitiy); //works fine
}

作者:

public void writeItems(List<Object> items) {
    //loops and casting
    commentRepository.save(comment); //LazyInitializationException
}

这里是完整的错误:

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.test.AnswerEntitiy.comments, could not initialize proxy - no Session

【问题讨论】:

  • “使用存储库获取”是什么意思?您的意思是从批处理作业存储库直接调用 jdbc 获取数据吗?
  • 当我使用方法查询时没有问题。我在上面添加了完整的示例。
  • wildfly 9.0.1 使用 jberet 吗?
  • 是的,WildFly 9 包含 JBeret 作为其批处理子系统提供程序。
  • 表面上看起来像是 JPA / Hibernate 配置问题。你检查过AnserEntity 中的@OneToMany 注释,可能是CommentEntity 的集合关系字段吗?在那里您应该能够指定适当的提取类型。

标签: hibernate ejb wildfly-9 java-batch jberet


【解决方案1】:

我假设您使用 JPA 来获取您的实体。显然,在您访问评论时,加载您的问题的 PersistenceContext 不再可用,因此您会遇到该异常。

作为一种解决方案,您必须在与核心实体字段相同的上下文中加载评论。我看到了这些可能性:

  1. 检查是否可以增加持久性上下文的范围。在所有事务确实跨越每个块的读取器、处理器和写入器之后,PersistenceContext 可能会出现类似的情况。
  2. 即使您的实体被声明为延迟获取,您也可以覆盖查询的该设置,或者通过在阅读器中访问它来显式加载评论字段。这会使延迟加载无效,但肯定会起作用。如果您有时只需要该字段,则可能会受到处罚。
  3. 最后一种可能性是将所有附加数据加载到处理器的 PersistenceContext 中,这是您已经评估过的。优点是它确实有效,并且不会失去延迟加载的优势。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-31
    • 1970-01-01
    • 2018-03-18
    • 2021-06-27
    • 2012-05-28
    相关资源
    最近更新 更多