【问题标题】:oneToMany/ManyToOne objects stale when updated outside the applicationoneToMany/ManyToOne 对象在应用程序外部更新时过时
【发布时间】:2016-01-11 16:30:39
【问题描述】:

最近才开始出现这种情况,我无法找到造成它的原因或如何解决它。 我有 2 个通过连接相互关联的对象

子实体:

@OneToMany(mappedBy = "child", cascade={ CascadeType.PERSIST, CascadeType.MERGE })
@JoinColumn(name="CHILD_ID", nullable=false)
private List<Parent> userCommunityOrganization = new ArrayList<Parent>();

父实体:

@JoinColumn(name = "CHILD_ID", referencedColumnName = "CHILD_ID")
@ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE },optional = false)
private Child child;

在应用中查询数据看起来像这样:

em.createQuery("SELECT p.child FROM Parent p "
      + "WHERE p.community.communityId = :communityId ")
      .setParameter("communityId", communityId)
      .setHint(TopLinkQueryHints.REFRESH, HintValues.TRUE);

症状:

直接在数据库中更新父字段(将状态从活动更改为非活动) - 或任何其他关系。

在应用程序中访问子对象, 应用程序中的父字段已过时(例如状态 = 活动),并且在服务器重新启动或应用程序重新部署之前将一直保持这种状态。

这不会影响孩子,当重新查询时,对数据库的更新会反映在应用中的孩子。

所有实体中的所有关系都会发生这种情况。
我试过改变缓存:

<property name="eclipselink.cache.shared.default" value="false"/>
<property name="eclipselink.query-results-cache" value="false"/>

从 javaEE 7 退回到 javaEE 6(这是自问题开始以来唯一的系统范围更改)。

没有快乐。有什么想法吗?

使用修复更新

我替换了这些行:

<property name="eclipselink.cache.shared.default" value="false"/>
<property name="eclipselink.query-results-cache" value="false"/>

与:

<property name="toplink.cache.shared.default" value="false"/>

现在我所有的关系在数据库中更新时都是同步的。我正在使用 toplink,即使 eclipselink 是 TL 的一个子集,我想这并没有扩展到所有参数。 eclipselink.query-results-cache 没有做任何事情,有一次我使用的是命名查询,但在执行期间添加查询提示会消除命名查询的查询缓存。

但我仍然想知道“为什么?”。哪些应用程序范围的变化会导致这种行为变化?

环境:

  • Java 7
  • glassfish 4.1
  • jpa 1.0(不要评判我)
  • toplink/eclipselink
  • 重量 2.3
  • smartgwt
  • MySql

【问题讨论】:

  • TopLinkQueryHints 来自哪个包?如果它来自 TopLink Essentials,它基于 TopLink,而不是基于 EclipseLink,并且可能解释了为什么忽略 EclipseLink 查询提示。它没有解释为什么这曾经有效 - 您确定它“有效”,而不仅仅是您没有注意到由于时间问题而出现的任何问题?
  • 它来自 oracle.toplink.essentials。这让我感觉更好,这本不应该奏效,但我已经确认它在我们的生产环境中确实有效。

标签: java jpa eclipselink smartgwt glassfish-4.1


【解决方案1】:

您正在使用刷新提示查询子级,该刷新提示仅强制刷新子级及其关系,而不是引用的实体。如果您希望引用的实体也被刷新,则必须使用级联刷新选项标记这些关系。

【讨论】:

  • 谢谢,但正如我在问题中所说,这直到最近才有效。在整个应用程序中具有关系的所有对象都会发生这种情况,这些查询提示保持不变。我会用解决方案更新问题,但我仍然不知道是什么导致了问题。
  • 刷新只对直接被查询的实体起作用。您的应用程序可能一直在其他线程中直接查询子实体和父实体,这将导致它们独立刷新并根据查询的时间显示刷新 - 但如果没有级联设置,则无法引用实体应该会刷新您显示的查询。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-03
  • 2020-07-19
  • 1970-01-01
  • 2018-10-11
  • 2020-09-14
相关资源
最近更新 更多