【问题标题】:After updating an entity that has Lazy Loaded attributes JOIN FETCH has no effect更新具有延迟加载属性的实体后,JOIN FETCH 无效
【发布时间】:2012-10-04 14:31:20
【问题描述】:

我们有这样的实体:

public User {
    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinColumn(name = "user_id", insertable = true, updatable = true)
    @ElementDependent
    private List<Item_x> item_x_list = new ArrayList<Item_x>();
}

public Item_x {
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id", insertable = true, updatable = true)
    @Element(name = "user_id", required = false)
    private Users user;
}

每当我向 User.item_x_list 添加/删除项目,然后使用 em.merge(User.INSTANCE) 持久化 User 实体时,Item_x.user 属性为 NULL。

我正在使用 JOIN FETCH 查询加载 Item_x.user 属性,以确保加载该属性(当我需要它时)。但是:如果您对用户实体执行了合并,即使使用 FETCH JOIN,Item_x.user 属性也是 NULL。

我尝试通过刷新 Item_x.INSTANCE 来解决 但是当我打电话时:

em.refresh(Item_x.Instance);

=> 用户为空。

查看数据库我当然可以看到Item_x中的用户不是空的。

如何强制 OpenJPA 在 Item_x 中正确加载用户? 为什么 OpenJPA 没有正确填充 Item_x.user 属性/忽略 JOIN FETCH 语句?

【问题讨论】:

  • 急于加载?仅在需要时才获取用户-我猜这就是懒惰的意义。
  • 是的,但问题是在更新实体“Item_x”后,Item_x 的用户属性(我之前使用 JOIN FETCH 查询强制获取)再次为空。那就是问题所在。我在 em.refresh(Ite​​m_x.Instance); 中看不到解决方案;因为它将返回相同的实体,但 Item_x.user = NULL。同样重新运行 FETCH JOIN 也不会填满用户。那么如何强制实体加载 Item_x.user ?
  • 尝试改写你的问题。您遗漏了太多细节,让别人有机会回答您的问题。
  • @Rick:我刚刚做到了。

标签: java jpa persistence lazy-loading openjpa


【解决方案1】:

看起来问题在于您创建了两个单向关系而不是双向关系。您的一个类需要定义与另一个类的 mappedBy 关系,该关系将另一个类定义为关系的“所有者”。例如,您可以将上面的示例更改为将 Item_x 定义为所有者,如下所示:

public User {
    @OneToMany(targetEntity = Item_x.class, mappedBy = "user", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @ElementDependent
    private List<Item_x> item_x_list = new ArrayList<Item_x>();
}

public Item_x {
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id", insertable = true, updatable = true)
    @Element(name = "user_id", required = false)
    private Users user;
}

OpenJPA documentation 中提供了更多信息,但它们缺少示例以使其更加清晰。

【讨论】:

  • 当我按照建议添加 mappedBy 时,效果是:当我将新条目 Item_x 添加到 User.item_x_list 的列表中,然后调用 em.merge(User.INSTANCE) 数据库中的生成记录时Item_x 表有一个值为 NULL 的用户列。
  • 尝试删除@Element注解;我把它留在那里是因为你有它,但我认为它实际上不应该在那里。
  • @Element 注解来自 XML 序列化:org.simpleframework.xml.Element => 这应该不会影响 openJPA 的持久化策略。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-13
  • 2013-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-17
  • 2014-03-26
相关资源
最近更新 更多