仅选择 HQL 中链接实体中的列子集



请不要问我为什么需要这样做,因为即使我认为我可以找到另一种方法来解决我的特定问题,我也想更多地了解HQL及其限制。

给定以下实体

@Entity
class Child {
    private String someAttribute1;
    .....
    private String someAttributeN;
    @ManyToOne(EAGER)
    private Parent parent;
}
class Parent {
    private String someParent1;
    ....
    private String someParentN;
}

如果我select Child那么 Hibernate 会自动从单个连接的 SQL 中获取ChildParent中的所有列,这是典型的理想情况。

有时我知道,对于映射了大量列的实体,我只需要一个子集。

如果我select item.someAttribute1 as someAttribute1, item.someAttribute2 as someAttribute2, item.someAttribute3 as someAttribute3 from Child item等绑定到ResultTransformer,我可以让 Hibernate 只从 SQL 中返回 3 列,如果我列出它们,则返回更多列。好吧,这很酷,就像一个魅力。

但是,如果我只需要从Child中获取 3 列,从Parent中获取 2 列,而其余的可以为空,并通过其关系实现Child实体,我不能写以下内容

select item.someAttribute1 as someAttribute1, item.someAttribute2 as someAttribute2, item.someAttribute3 as someAttribute3, item.parent.someParent1 as parent.someParent1, item.parent.someParent2 as parent.someParent2 from Child item left join item.parent

上述方法不起作用,因为 Hibernate 不允许编写别名。它不允许我使用as parent.someName子句,因为别名可能应该是平面的。

举一个反例,在 LINQ 等语言中,问题不适用

from Child c in children
select new Child {
    SomeAttribute1 = c.someAttribute1,
    SomeAttribute2 = c.someAttribute2,
    Parent = new Parent {
        Attribute1 = c.Parent.Attribute1,
        .......
    }
}

使用上述语句,实体框架将仅获取所需的列。

我绝对不想在Hibernate的Java和Entity Framework for C#之间进行比较或批评。

我只需要获取组成具有@ManyToOne关系的实体的列的子集,以优化内存和带宽使用。一些列来自子实体,一些列来自父实体。

我只想知道在Hibernate中是否以及如何实现这样的事情。使用仅填充列子集的类 Parent 的对象填充结果集中parent属性(其余为 null 没有问题)。我愉快地使用ResultTransformer

它有两个问题。

  1. Hibernate不允许使用嵌套别名,如HQL中的as parent.someName。它会产生解析错误。但是您可以将嵌套别名与Criteria一起使用 Projections.property("parent.someName") .

  2. Hibernate 没有使用嵌套别名填充结果对象的结果转换器。

可以将Criteria请求与自定义结果转换器一起使用,如此处所述

如何使用休眠转换平面结果集

最新更新