【问题标题】:JPA get values from the collections in entitiesJPA 从实体中的集合中获取值
【发布时间】:2011-04-03 22:13:01
【问题描述】:

我是 JPA 的新手,现在遇到了一个问题!

我有两个表 PersonPersonAddress

Person 实体中,我有

@OneToMany(mappedBy="personid")
private Set<Personaddress> personaddressCollection;

public Set<Personaddress> getPersonaddressCollection() {
    return this.personaddressCollection;
}

public void setPersonaddressCollection(Set<Personaddress> personaddressCollection) {
    this.personaddressCollection = personaddressCollection;
}

PersonAddress 实体中,我有

@ManyToOne
@JoinColumn(name="PERSONID")
private Person personid;

我正在做一个类似于下面的查询:

List<Person> personlist = em.createQuery("SELECT e FROM Person e").getResultList();

我希望它返回 Person 表中的所有数据以及 Person 实体中可用的 Set 中的 PersonAddress 表中的数据。 personlist 的大小是正确的,但是当我尝试读取 PersonAddress 集合时,我得到的是空值。但数据库中有值,不能为空。

对应每一个Partner,都会有一个不为空的PartnerAddress。 如果到目前为止我所做的任何事情都是错误的,我该如何使用 JPA 查询它?

请帮忙。

【问题讨论】:

  • 如果可能(即班级人数很少),您能否发布完整的 Person 和 PersonAddress 班级?
  • 不是一个答案,而是两个提示:1)初始化集合(例如new HashSet&lt;PersonAddress&gt;()),这可以防止 NPE 和 2)不为集合本身提供设置器,您的客户可以直接修改getter 返回的集合。您的 JPA 提供者可能已经注入了优化的集合实现,您应该使用它。
  • 文件在这里 - bit.ly/d4TEAd

标签: java jpa jakarta-ee persistence


【解决方案1】:

我希望它返回 Person 表中的所有数据以及 Person 实体中可用的 Set 中的 PersonAddress 表中的数据。

OneToMany 默认为LAZY,因此SELECT e FROM Person e 不会加载关联地址的集合。

如果你想改变这种行为,要么让关联变得急切:

@OneToMany(mappedBy="personid", fetch=FetchType.EAGER)
private Set<Personaddress> personaddressCollection;

或者使用 FETCH JOIN 预取关联:

SELECT e FROM Person e LEFT JOIN FETCH e.personaddressCollection

使用后一种方法,当您不需要地址时,您仍然可以从延迟加载中受益。前一种方法“全局”地改变了行为。

personlist 的大小是正确的,但是当我尝试读取 PersonAddress 集合时,我得到的是空值。但数据库中有值,不能为空。

这在某种程度上是“另一个”问题。我的建议是激活 SQL 语句的日志记录,以查看究竟执行了哪些查询以及为什么没有获得相应的地址。数据肯定有问题。

参考文献

  • JPA 1.0 规范
    • 第 9.1.24 节“OneToMany 注释”
    • 第 4.4.5.3 节“获取连接”

【讨论】:

  • “OneToMany 默认是 LAZY,因此 SELECT e FROM Person e 不会加载关联地址的集合。”:第一部分是正确的,但不是第二部分。集合被加载,只是加载被推迟到调用 getter 方法。这由集合的 getter 上的代理对象处理。因此,获取策略中不能存在导致返回空值的错误。记录 SQL 的建议势必对 OP 有所帮助。我要求提供完整的类列表,因为我认为类-实体关系未被正确识别。
  • @Vineet 我不是这么说的。我解释了问题的第一部分“我希望它返回 Person 表中的所有数据以及以及 Person 实体中可用的 Set 中的 PersonAddress 表中的数据”就像是关于 EAGER fetching 这就是为什么我写了几句话关于 OneToMany 默认是 LAZY 的原因。但我没有写到这可能会导致得到null,实际上明确写到这是“另一个” 问题。换句话说,也许第一部分超出了 OP 的要求,但我仍然认为我的回答是正确的,你正在阅读我没有说的内容。
  • @Pascal,我的错。我只能尴尬地道歉:-)
  • @Vineet 没问题,别担心。也许我的答案毕竟不是很清楚。我将等待 OP 的一些反馈,然后再更新。
  • 我选择了 SELECT e FROM Person e LEFT JOIN FETCH e.personaddressCollection 。它现在工作正常。也许是因为我正在尝试一些东西,并在插入后立即执行了查询。我将它们分开并再次尝试,效果很好..!感谢大家的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-03-18
  • 2017-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-19
  • 1970-01-01
相关资源
最近更新 更多