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

时间:2016-01-27 15:32:11

标签: java hibernate hql

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

鉴于以下实体

@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列,而其余列可以为null,并实现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,
        .......
    }
}

通过上述声明,Entity Framework将只获取所需的列。

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

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

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

1 个答案:

答案 0 :(得分:1)

它有两个问题。

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

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

  3. 您可以使用#include <stdio.h> #include <stdlib.h> #define LEN(arr) (sizeof (arr) / sizeof (arr)[0]) #define NEW_ARRAY(ptr, n) (ptr) = malloc((n) * sizeof (ptr)[0]) typedef struct { int m; int n; char **table; } Matrix; int main() { const char items[2][3] = {{' ', 'x', ' '}, {'x', 'x', 'x'}}; Matrix A; int i, j; A.m = LEN(items); A.n = LEN(items[0]); /*initialize matrix*/ NEW_ARRAY(A.table, A.m); for (i = 0; i < A.m; i++) { NEW_ARRAY(A.table[i], A.n); for (j = 0; j < A.n; j++) { A.table[i][j] = items[i][j]; } } /*print matrix*/ for (i = 0; i < A.m; i++) { for (j = 0; j < A.n; j++) { printf("%c ", A.table[i][j]); } putchar('\n'); } return 0 ; } 请求与此处所述的自定义结果转换器

    How to transform a flat result set using Hibernate