JPA (EclipseLink) 在列表中返回 null

JPA (EclipseLink) returning null in list

我不知道删除原来的问题是否合适,但在底部添加了更简洁的解释,希望这样就无需查看所有细节。


我收到不一致的结果,无法弄清楚我做错了什么。它涉及一个带有容器管理实体管理器的 EE7 网络应用程序,Java 8,EclipseLink 2.5.2,netbeans 8.0.2 IDE。

有一个 parent child 关系映射为 bi-directional 关系:

事件 Table 是映射到游戏

的 parent
@OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "event")
@OrderBy("gameType, round")
private List<Game> gameList;

游戏将事件映射为

@JoinColumn(name = "EVENT", referencedColumnName = "ID")
@ManyToOne(fetch = FetchType.EAGER, optional = false)
private Event event;

第一步: 我使用 Web 界面创建了一个事件和一个游戏。游戏被添加到事件列表和事件到游戏。 em.persist(event) 被调用以保存所有内容。 -> 效果很好

第 2 步: 编辑活动 创建一个新游戏 - 将事件添加到游戏中,em.persist(game) 与 em.flush() 获取 id 并将其添加到事件中的游戏列表 所有编辑完成后 em.update(事件) -> 数据库完全按照预期更新 -> 顺便说一句,我知道在事件准备好保存以允许 'quit' 选项之前不坚持游戏是更好的用户体验。这是我打算做的事情,但还没有很好地掌握这样做的最佳实践,而且我在级联方面的经验好坏参半。

最后的问题: - 100% 的时间 'step two' 与数据库一起正常工作,但是当我检索事件以进行进一步编辑时,该事件在游戏列表中有一个附加条目,值为 null。 - 如果我一遍又一遍地关闭并重新启动应用程序,有时会发生,有时不会。数据库始终保持完好无损,完全符合预期 - 同时使用来自同一台机器或其他机器的不同浏览器具有相同的结果 - 显然持久性缓存可能处于不一致状态,但我无法确定我是否做错了什么或遇到 EclipseLink 错误

早些时候我报告了一个 结果是与 IndirectList class 和 Java 8 相关的 EclipseLink 错误所以我不确定我是否做错了什么或如果这是相似的。

提前致谢!

在阅读了 JPA JSR 之后,我想知道我的理解是否正确。在 Web 应用程序中使用 EE 容器管理的事务范围内的持久上下文本质上意味着事务以对 EJB 的方法调用开始并以 return 结束。因此,获取信息以将某些内容显示在屏幕上是一项事务,而在用户更改后进行更新则是另一项事务。或者更清楚地说,我几乎总是与分离的实体一起工作。

我的方法是获取实体树,让 user/administrator 更新任何必要的内容,然后根据需要保留、合并或删除。由于它是分离的孤儿移除不起作用所以我直接这样做但保持关系。我还直接保留新的 children 并假设我可以 em.merge parent 尽可能多,因为它已附加,应用更改并且我的实体与数据库保持一致。

这是一种公平的方法还是存在某种缺陷?


我仍然遇到这个问题,可能已经进一步跟踪了它。我有许多相关记录,这些记录通过外键@ManyToOne 和@OneToMany bi-directional 链接。

它本质上是一个带有反向链接的简单链:

重现步骤:

  1. new C(B,以及其他构造函数参数)
  2. B.add(C)
  3. 在 C 中设置其他属性
  4. em.persist(C)保证一个ID
  5. em.update(B) 注册更新关系

在包括 4 在内的每一步之后,一切看起来都是正确的。我想也许第 2 步应该跟在第 4 步之后,但我不确定它会有所作为。 第 5 步之后,

随后,当我使用 em.find() 刷新实体时,实体 B 在列表 C 中有 NULL 条目,尽管 MySQL 数据库反映了我的预期。

我显然做错了什么破坏了 EclipseLink 持久缓存。我发现唯一可以解决此问题的方法是重新启动应用程序以删除缓存。

几个月来我一直无法解决这个问题,希望得到任何建议。

问题最终被追踪到编码错误。具体来说,从 em.merge() 返回的引用指针未在相关实体中更新,从而导致多个副本并破坏持久性。

启动顺序中的某些内容会影响此损坏是否随着列表中的 null 症状变得明显或一切正常。它看似零星,但实际上是早期腐败的结果。