gpt4 book ai didi

java - 使用 JPA/Hibernate 保留大型对象图时出现异常

转载 作者:行者123 更新时间:2023-12-02 07:19:41 25 4
gpt4 key购买 nike

我们正在创建一个由 JPA 支持的新 Web 应用程序来替换旧的 Web 应用程序。作为迁移的一部分,我们将旧应用程序的数据库转换为新的、更复杂的、JPA 管理的数据库。

所以我编写了一个“脚本”,将旧数据库转换为一组 JPA 实体,然后保存它们。它的工作原理如下:

  1. 根据领域模型的依赖关系创建转换顺序
  2. 对于每个实体
    1. 对旧数据库执行数据库查询
    2. 将每个获取的表行的新对象存储在内存列表中
  3. 按照与转换相同的顺序迭代生成的列表,并保留每个实体。

现在,前两个步骤效果很好。然而,在坚持之后,我得到了一个异常(exception)。当一个实体与另一实体有关系时,就会出现异常。例如,如果我们的实体之一是 Book另一个是 Chapter定义 @ManyToOne(optional=false)Book 相关。持久化章节后,它会抛出异常 java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: Not-null property references a transient value - transient instance must be saved before current operation: models.Chapter.book -> models.Book .

当然,这表明这本书的状态有问题:它似乎尚未设置或尚未持久化。但是,我可以验证 BookChapter 的转换中正确设置,我还可以验证 Book 类型的所有实体EntityManager 持续存在 Chapter 类型的实体之前坚持下去。显然,我的 JPA 提供程序的行为不符合预期,并且没有真正保留我的 Book由于某种原因对象。

什么解决方案可以让我保存已转换到数据库的整个对象图?我使用 Hibernate 作为我的 JPA 提供程序,还使用 ​​Spring 3.1 来注入(inject)依赖项和 EntityManager s。

编辑1:一些附加信息:我再次验证了在各章节上调用entityManager.persist()之前,对每个书籍对象调用了entityManager.persist()。但是,图书对象的 id 仍然为空,这意味着它没有正确持久化。尽管不使用事务,数据库也仍然是空的。

编辑2:因为我认为上面的文字并不清楚:书和章节的故事只是一个例子。对于引用另一个实体的任何实体都会发生这种情况。这使得我看起来好像没有正确使用 JPA/Hibernate,而不是没有正确设置实体的值。

编辑3:核心问题似乎是尽管正确地保留了 Book 并具有所有正确的注释,但 book.getId() 仍然为空。基本上,Hibernate 在持久化实体后不会在实体上设置 id,这会导致我稍后需要使用这些实体时出现问题。

最佳答案

我自己曾经在 hibernate 时遇到过这样的错误。原来是对象图中的一个圆圈和级联设置的组合导致了问题。

已经有一段时间了,所以捕鸟可能不是 100% 准确,但也许它足以跟踪您的问题:

  1. Hibernate 想要插入章节。意识到需要先插入
  2. 想要插入这本书。意识到需要先插入另一个实体(例如发布者)
  3. 插入发布者并执行发布者定义的级联(例如作者)
  4. 作者有例如引用他的最新书籍。因为 hibernate 内部已经将书标记为已处理(在步骤 2 中),所以您不会收到异常,指出author.book 引用了 transient 实例。

要查明这是否是您的问题,您可以启用完整的 hibernate 调试并遵循 hibernate 在对象图中所采用的路径。

关于java - 使用 JPA/Hibernate 保留大型对象图时出现异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14416290/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com