Hibernate query with an alias
Asked Answered
D

2

6

What's wrong with

session.createCriteria(Composed.class, "main")
.createAlias("main.id.branch", "b1")
.add(Restrictions.eq("b1.owner", user))
.list();

? The corresponding HQL works fine

String hql = "select main from Composed as main"
        + "left join main.id.branch as b1 where b1.owner = ?";
session.createQuery(hql)
.setInteger(0, user.id().intValue())
.list();

From the Criteria, Hibernate creates no join and uses where b1x1_.owner_id=?, but there's no b1x1_ anywhere, so it fails with "could not prepare statement".

The classes are rather trivial

@Entity class Composed {
    @Id ComposedId id; // also tried @EmbeddedId
    ... irrelevant stuff
}

@Embeddable class ComposedId {
    @ManyToOne(optional=false) Branch branch;
    ... irrelevant stuff
}

@Entity class Branch {
    @Id Integer id;
    @ManyToOne(optional=false) User owner;
    ... irrelevant stuff
}

@Entity class User {
    @Id Integer id;
    ... irrelevant stuff
}

Update

I've finally created an SSCCE and filed an issue. Sorry for the confusing question, without the SSCCE, it's rather hard to reproduce.

Dit answered 5/12, 2015 at 12:35 Comment(8)
Not sure, but did you try creating alias in steps? say first for main.id=x1 then x1.branch= x2 and so on.?Datura
@Datura Now, I did. IMHO there's no need for aliasing main.id as it's embedded, but I've tried it. I've also tried to create the alias for main.id only and whatelse.Dit
Could you try Restrictions.eq("b1.owner.id", user.id().intValue())? Could you also share whole generated SQL and error message.Pigeonhearted
Aren't you missing mapping on Use owner;[sic] field in Branch class?Pigeonhearted
What hibernate version are you using? With your annotated classes in the question, I cannot even create a SessionFactory. I get the following exception: INFO: HHH000400: Using dialect: org.hibernate.dialect.HSQLDialect Exception in thread "main" java.lang.NullPointerException at org.hibernate.cfg.Configuration.processFkSecondPassInOrder(Configuration.java:1499) at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1422) at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1846)Trudi
@VlastimilOvčáčík I'm afraid I made quite a few mistakes when extracting this example from my real code. I fixed it now. And no, there's missing mapping problem (quite a few other queries work well).Dit
@NathanKummer See my above comment. I'm using 5.0.4., but the problem was probably missing @Id on Integer id. I'll try to create an self-contained executable example when I get some spare time (for now, I'm sticking with the HQL).Dit
Yes. I made changes to the model the way that I thought it ought to look and as soon as I did that, both the criteria and the hql worked just fine.Trudi
S
2

I didn't try but maybe creating two aliases with left join helps you. I mean this:

session.createCriteria(Composed.class, "main")
   .createAlias("main.id", "id1", JoinType.LEFT_OUTER_JOIN)
   .createAlias("id1.branch", "b1", JoinType.LEFT_OUTER_JOIN)
   .add(Restrictions.eq("b1.owner", user))

Hope it helps!

Slave answered 8/12, 2015 at 9:38 Comment(0)
S
0

You need a sub criteria for the join instead of an alias since Branch is a mapped Entity.

session.createCriteria(Composed.class, "main")
    .createCriteria("main.id.branch", "b1")
    .add(Restrictions.eq("b1.owner", user))
    .list();
Summation answered 15/12, 2015 at 2:32 Comment(3)
No idea, if this really helps, and no time to try it out now, but the bounty is going to expire soon. Could you elaborate on the reason why I need sub criteria?Dit
You said Hibernate creates no join which is the result of you not instructing hibernate to do so. When you create a sub criteria you force hibernate to create a join. I have no experience yet with embeddable but i assume they behave the same as components. I did not tested it either, but wrote down on how I do it. Don't rush for the bounty, if it expires it does.Summation
Unfortunately, it doesn't work either. I guess, in the meantime I've tried all possibilities. I regret having used composed id, as Hibernate is broken on this side. I've even tried JPA with hibernate-jpamodelgen, but it generates nothing for my ComposedId, so I'm lost again. Maybe it's because of me using a static nested class.Dit

© 2022 - 2024 — McMap. All rights reserved.