If someone still wonders about this issue - unfortunetly this is a bug in hibernate which havent been fixed yet.
Hibernate criteria: creating alias with entity through another entity with embeddedId
-
04-08-2022 - |
Question
I couldn't find better questions so I hope it shows what I am asking.
I have 3 entities ( i will only write code that really matters for better reading
Foo.java
@Data
@Entity
@Table(name = "foo", schema = "pl")
@SequenceGenerator(name = "sequence_generator", sequenceName = "pl.foo_seq", allocationSize = 1)
@EqualsAndHashCode(callSuper = false, exclude = {"Doos" })
@ToString(callSuper = true, exclude = { "Doos" })
public class Foo extends BaseEntity{
[...]
@OneToMany(mappedBy = "pk.foo")
private Set<FooDooRel> Doos= new HashSet<FooDooRel>();
public void addDoo(FooDooRel fooDooRel) {
if (fooDooRel== null) {
return;
}
if (!Doos.contains(fooDooRel)) {
Doos.add(fooDooRel);
}
}
[...]
}
FooDooRel.java(has private contructor FooDooRel())
@Getter
@Setter
@Entity
@Table(name = "foo_doo_rel", schema = "pl")
@EqualsAndHashCode
@ToString(callSuper = true, exclude = { "pk" })
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class FooDooRel implements IEntity {
@EmbeddedId
private FooDooRelId pk;
public FooDooRel(Doo doo, Foo foo) {
if (doo == null || foo == null) {
throw new IllegalArgumentException("Foo or Doo equals null");
}
doo.addFoo(this);
foo.addDoo(this);
pk = new FooDooRelId(doo, foo);
}
[...]
}
FooDooRelId.java (has private contructor FooDooRelId())
@Getter
@Setter
@Embeddable
@EqualsAndHashCode
@ToString(callSuper = true, exclude = { "doo", "foo" })
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class FooDooRelId implements Serializable {
@ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.REFRESH })
@JoinColumn(name = "doo_id")
private Doo doo;
@ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.REFRESH })
@JoinColumn(name = "project_id")
private Foo foo;
public FooDooRelId(Doo doo, Foo foo) {
setDoo(doo);
setFoo(foo);
}
}
Doo.java
@Data
@Entity
@Table(name = "doo", schema = "pl")
@SequenceGenerator(name = "sequence_generator", sequenceName = "pl.doo_seq", allocationSize = 1)
@EqualsAndHashCode(callSuper = false, exclude = {"Foos" })
@ToString(callSuper = true, exclude = { "Foos" })
public class Doo extends BaseEntity{
[...]
@OneToMany(mappedBy = "pk.doo")
private Set<FooDooRel> Foos= new HashSet<FooDooRel>();
@Column(name = "dispid", nullable = false)
private String dispid;
public void addFoos(FooDooRel fooDooRel) {
if (fooDooRel== null) {
return;
}
if (!Foos.contains(fooDooRel)) {
Foos.add(fooDooRel);
}
}
[...]
}
Now I have to create Aliases for my filter so
Criteria criteria = getSession().createCriteria(Foo.java, "foo")
criteria.createAlias("Doos", "Disp5", JoinType.LEFT_OUTER_JOIN, Restrictions.eq(Disp5.pk.foo.dispid", "5"));
Now first error, when I do this i get this error
could not resolve property: pk.foo.dispid of: pl.FooDooRel
I also tried
criteria.createAlias("Foos", "fooRel", JoinType.LEFT_OUTER_JOIN).createAlias("fooRel.pk.doo", "doo5",
JoinType.LEFT_OUTER_JOIN, Restrictions.eq("dispid", "5"));
or
criteria.createAlias("Foos", "fooRel", JoinType.LEFT_OUTER_JOIN).createAlias("fooRel.pk.doo", "doo5",
JoinType.LEFT_OUTER_JOIN, Restrictions.eq("doo5.dispid", "5"));
I understand i have to do second JOIN to join FooDooRel with Doo but I dont know how to do this. I can create alias for FooDooRel but how, in the same criteria go further to Doo.
second one, i have to do 2 aliases from same Set when I do this
Criteria criteria = getSession().createCriteria(Foo.java, "foo")
criteria.createAlias("Doos", "Disp5", JoinType.LEFT_OUTER_JOIN, Restrictions.eq(Disp5.pk.foo.dispid", "5"));
criteria.createAlias("Doos", "Disp6", JoinType.LEFT_OUTER_JOIN, Restrictions.eq(Disp5.pk.foo.dispid", "6"));
I get an error, that path is duplicated
So first, how can I join FooDooRel to Foo by checking dispid in Doo, and second how can I join 2 aliases from same path?
I can't use sub-query (DetachedCriteria).
I didn't want to write alot, but on my previous question someone told my that my god isnt good, so I have added all that i think i should I have added. This is basicly example of 3 entities that are connect by @ManyToOne
from "inside". Also one entity had embeddableId
. I hope you will understand my entities, my question is about criterias, and creating alias for first entity by adding criterion from third one.
Solution