【问题标题】:use case in the book "Java Persistence with Hibernate, 2nd Edition"“Java Persistence with Hibernate, 2nd Edition”一书中的用例
【发布时间】:2020-06-19 15:51:40
【问题描述】:

我正在阅读“Java Persistence with Hibernate, 2nd Edition”一书。它以出售给 ebay 等竞标者的商品为例。在第 400 页,作者说

查询select i from item i left join fetch i.bids b where b.amount > 20 无效。您不能说“加载 Item 实例并初始化它们的投标集合,但只能使用具有一定数量的投标实例。”

我不确定是否完全理解。我认为它是有效的,但它只会呈现出价大于 20 的项目。在这种情况下,它将呈现具有该条件的内部连接

另外下面的请求select i from item i left join fetch i.bids b on b.amount > 20有效吗?

【问题讨论】:

  • 这个例子是关于 HQL(Hibernate 的查询语言)而不是 SQL 本身,对吗?
  • 是的,它是关于 HQL

标签: hibernate hql


【解决方案1】:

select i from item i left join fetch i.bids b where b.amount > 20 因为 HQL 无效。因为 HQL 结果用于返回 Item 对象,所以您不能告诉 hibernate 请创建 Item 对象,但是当您创建它时,不要用 all @987654325 填充它@s 但仅填充数量大于 20 的 Bids。

考虑下面的类

public class Item {
    String name;
    Collection<Bid> bids;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Collection<Bid> getBids() {
        return bids;
    }

    public void setBids(Collection<Bid> bids) {
        this.bids = bids;
    }
}

更新:(让我们通过一个示例来看看如果 hibernate 允许此查询会发生什么)

如果休眠允许它发生的主要问题:

  1. 第一个问题这在概念上是错误的,因为使用从 repo 返回的 item1 java 对象的任何服务都不知道 item.getBids 仅包含金额 > 20 的投标
  2. Hibernate 只保留一个对象引用来表示会话中的数据库实体(可重复读取保证、脏检查等)。因此,如果您再执行一次Select i from Item i where i.itemId = 1 ,hibernate 就会出现问题,因为现在它必须有两个 java 对象来表示该会话中的项目 1(一个具有金额 > 20 的出价,另一个具有项目 1 的所有出价)

希望这能清楚地解释为什么不允许查询

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-11
    • 2022-06-14
    • 2011-09-19
    • 2012-05-03
    • 1970-01-01
    • 2011-06-28
    • 2013-02-18
    相关资源
    最近更新 更多