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 链接。
它本质上是一个带有反向链接的简单链:
- 实体 A 包含 B 的列表,B 是 A 的外键
- 实体 B 包含 C 的列表,C 是 B 的外键
重现步骤:
- new C(B,以及其他构造函数参数)
- B.add(C)
- 在 C 中设置其他属性
- em.persist(C)保证一个ID
- em.update(B) 注册更新关系
在包括 4 在内的每一步之后,一切看起来都是正确的。我想也许第 2 步应该跟在第 4 步之后,但我不确定它会有所作为。
第 5 步之后,
- B 具有相同的内存位置和指向 C 的指针。
- C 已更新为引用 B 和 A 的新内存位置。
- 即指向 C 中 B 和 A 的指针是与源不同的内存位置
随后,当我使用 em.find() 刷新实体时,实体 B 在列表 C 中有 NULL 条目,尽管 MySQL 数据库反映了我的预期。
我显然做错了什么破坏了 EclipseLink 持久缓存。我发现唯一可以解决此问题的方法是重新启动应用程序以删除缓存。
几个月来我一直无法解决这个问题,希望得到任何建议。
问题最终被追踪到编码错误。具体来说,从 em.merge() 返回的引用指针未在相关实体中更新,从而导致多个副本并破坏持久性。
启动顺序中的某些内容会影响此损坏是否随着列表中的 null 症状变得明显或一切正常。它看似零星,但实际上是早期腐败的结果。
我不知道删除原来的问题是否合适,但在底部添加了更简洁的解释,希望这样就无需查看所有细节。
我收到不一致的结果,无法弄清楚我做错了什么。它涉及一个带有容器管理实体管理器的 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 错误
早些时候我报告了一个
提前致谢!
在阅读了 JPA JSR 之后,我想知道我的理解是否正确。在 Web 应用程序中使用 EE 容器管理的事务范围内的持久上下文本质上意味着事务以对 EJB 的方法调用开始并以 return 结束。因此,获取信息以将某些内容显示在屏幕上是一项事务,而在用户更改后进行更新则是另一项事务。或者更清楚地说,我几乎总是与分离的实体一起工作。
我的方法是获取实体树,让 user/administrator 更新任何必要的内容,然后根据需要保留、合并或删除。由于它是分离的孤儿移除不起作用所以我直接这样做但保持关系。我还直接保留新的 children 并假设我可以 em.merge parent 尽可能多,因为它已附加,应用更改并且我的实体与数据库保持一致。
这是一种公平的方法还是存在某种缺陷?
我仍然遇到这个问题,可能已经进一步跟踪了它。我有许多相关记录,这些记录通过外键@ManyToOne 和@OneToMany bi-directional 链接。
它本质上是一个带有反向链接的简单链:
- 实体 A 包含 B 的列表,B 是 A 的外键
- 实体 B 包含 C 的列表,C 是 B 的外键
重现步骤:
- new C(B,以及其他构造函数参数)
- B.add(C)
- 在 C 中设置其他属性
- em.persist(C)保证一个ID
- em.update(B) 注册更新关系
在包括 4 在内的每一步之后,一切看起来都是正确的。我想也许第 2 步应该跟在第 4 步之后,但我不确定它会有所作为。 第 5 步之后,
- B 具有相同的内存位置和指向 C 的指针。
- C 已更新为引用 B 和 A 的新内存位置。
- 即指向 C 中 B 和 A 的指针是与源不同的内存位置
随后,当我使用 em.find() 刷新实体时,实体 B 在列表 C 中有 NULL 条目,尽管 MySQL 数据库反映了我的预期。
我显然做错了什么破坏了 EclipseLink 持久缓存。我发现唯一可以解决此问题的方法是重新启动应用程序以删除缓存。
几个月来我一直无法解决这个问题,希望得到任何建议。
问题最终被追踪到编码错误。具体来说,从 em.merge() 返回的引用指针未在相关实体中更新,从而导致多个副本并破坏持久性。
启动顺序中的某些内容会影响此损坏是否随着列表中的 null 症状变得明显或一切正常。它看似零星,但实际上是早期腐败的结果。