1

Please don't ask me why I need to do this, as even if I think I could find another way to solve my specific problem, I want to understand HQL and its limits more.

Given the following entities

@Entity
class Child {

    private String someAttribute1;
    .....
    private String someAttributeN;

    @ManyToOne(EAGER)
    private Parent parent;

}

class Parent {

    private String someParent1;
    ....
    private String someParentN;
}

If I select Child then Hibernate automatically fetches all columns from Child and Parent in a single joined SQL, and that is the typical desired case.

Sometimes I know that, for entities mapped with a large number of columns, I need only a subset.

If I select item.someAttribute1 as someAttribute1, item.someAttribute2 as someAttribute2, item.someAttribute3 as someAttribute3 from Child item etc. tied to a ResultTransformer I can let Hibernate return me only 3 columns from the SQL, or more columns if I list them. OK, that is cool and works like a charm.

However if I need to fetch only, say, 3 columns from Child and 2 from Parent, while the rest can be null, and materialize a Child entity with its relationship, I cannot write the following

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

The above does not work because Hibernate does not allow an alias to be composed. It disallows me to use as parent.someName clause because aliases should probably be flat.

Just to tell a counter example, in languages such as LINQ the problem does not apply

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

    Parent = new Parent {
        Attribute1 = c.Parent.Attribute1,
        .......
    }
}

With the above statement, Entity Framework will only fetch the desired columns.

I don't want to make comparison or criticism between Hibernate for Java and Entity Framework for C#, absolutely.

I only have the need to fetch a subset of the columns that compose an entity with a @ManyToOne relationship, in order to optimize memory and bandwidth usage. Some columns from the child entity and some from the parent.

I just want to know if and how is it possible in Hibernate to achieve something like that. To populate parent attribute in the result set with an object of class Parent that is populated with only a subset of columns (the rest being null is no problem). I am using ResultTransformers happily

usr-local-ΕΨΗΕΛΩΝ
  • 26,101
  • 30
  • 154
  • 305
  • What exactly does not work in the query above? Perhaps I missed something, but it looks valid to me. The only thing wrong with it is that `left join` is ignored since you are using `item.parent` in the `select` clause which translates to `inner join`. To avoid that you should use `select item.a1, p.p1 from Child item left join item.parent p` – Predrag Maric Jan 27 '16 at 16:18
  • @PredragMaric He wants to use nested projection aliases like this `parent.someParent1` as I think. – v.ladynev Jan 27 '16 at 16:19
  • @v.ladynev You're probably right, didn't see that. Thanks. – Predrag Maric Jan 27 '16 at 16:28

1 Answers1

1

There are two problems with it.

  1. Hibernate doesn't allow to use nested aliases like as parent.someName in HQL. It produces a parsing error. But you can use nested aliases with Criteria using Projections.property("parent.someName").

  2. Hibernate doesn't have a result transformer to populate result objects using nested aliases.

You can use Criteria requests with a custom result transformer as described here

How to transform a flat result set using Hibernate

Community
  • 1
  • 1
v.ladynev
  • 19,275
  • 8
  • 46
  • 67