【问题标题】:Correct way to query an entity with nested collections?使用嵌套集合查询实体的正确方法?
【发布时间】:2013-03-30 07:13:52
【问题描述】:

当集合元素有自己的集合时,基本查询似乎不起作用。

想象一个银行的数据模型,其客户拥有投资组合和投资。获取客户的正确方法是什么?

我试过了:

@Query("SELECT DISTINCT c FROM Customer c LEFT JOIN FETCH c.portfolios")

但它失败并显示“无法延迟初始化角色集合”。

投资定义为:

@ManyToMany(cascade = CascadeType.ALL)

如果我更改 fecthType,查询将起作用:

@ManyToMany(cascade = CascadeType.ALL, fetch=FetchType.EAGER)

但是有没有办法让它在不改变 fetchtype 的情况下工作?

编辑:

我应该提到我使用 Spring 的 JpaRepository 来定义上述查询。所有实体都有各自的存储库,但看起来获取客户不会触及投资组合存储库中的任何方法(这将 LEFT JOIN 投资),因此永远不会获取投资。

另外,我可以使用类似的查询来获取投资组合,并且它工作正常,因为投资没有任何集合。但是获取连锁客户 -> 投资组合 -> 投资失败。

【问题讨论】:

  • 这应该对你有帮助:stackoverflow.com/questions/5404599/…
  • 我仍然不明白为什么它适用于具有集合的实体,但不适用于具有集合的实体......
  • 只是一个问题,使用多对一映射是否仍然会出现错误?
  • 我有另一个使用 @OneToMany 的案例,但同样失败。共同点是集合的元素也有集合。
  • 你能不带 DISTINCT 试试吗?

标签: hibernate jpa spring-data-jpa


【解决方案1】:

您的查询使用left join fetch 选择客户并获取他们的投资组合。如果你还想获取投资组合的投资,你需要一个额外的连接获取,就像在 SQL 中一样:

select distinct c FROM Customer c 
left join fetch c.portfolios portfolio
left join fetch portfolio.investments

【讨论】:

  • 你知道它为什么会抛出异常吗?我会理解如果他尝试访问投资,因为它们没有初始化,他为什么会得到这个异常,但在这里他没有尝试获取投资,为什么它会失败?我可能完全错了......
  • 谢谢,这行得通。但是如果我不需要它们怎么办?我如何告诉 hibernate/jpa 忽略投资而只获取客户和投资组合?
  • 如果您收到此异常,则表示您正在访问投资集合。如果您不需要它们,请在您的问题中执行查询,不要使用left join fetch portfolio.investments。您得到的异常准确地表明投资尚未加载。
  • “如果你得到这个异常,这意味着你正在访问投资集合” - 我想知道这可能发生在哪里,然后我意识到它已被转换为 JSON(这都是REST API)。访问投资的一定是JSON转换器!
猜你喜欢
  • 1970-01-01
  • 2011-10-20
  • 2020-06-18
  • 2011-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-26
相关资源
最近更新 更多