[英]Hibernate criteria on embedded id member member value
I would like to find an entity using a critera with restriction on the value of an attribute of a second entity wich is a member of the embedded id of my first entity. 我想找一个实体使用一个限制第二个实体的属性值的critera,它是我第一个实体的嵌入式id的成员。
First entity : 第一实体:
@Entity
public class Car {
@EmbeddedId
private Id id = new Id();
private String color;
@Embeddable
public static class Id implements Serializable {
private static final long serialVersionUID = -8141132005371636607L;
@ManyToOne
private Owner owner;
private String model;
// getters and setters...
// equals and hashcode methods
}
// getters and setters...
}
Second entity : 第二实体:
@Entity
public class Owner {
@Id
@GeneratedValue (strategy = GenerationType.AUTO)
private Long id;
private String firstname;
private String lastname;
@OneToMany (mappedBy = "id.owner")
private List<Car> cars;
// getters and setters...
}
In this example, I would like to obtain the car with the color 'black', model 'batmobile' and the owner's firstname 'Bruce' (oops... spoiler ;) ) 在这个例子中,我想获得颜色为“黑色”的车型,型号为“batmobile”,车主的名字为“Bruce”(oops ...剧透;))
I tried to do something like that but it won't work : 我尝试做类似的事情,但它不会起作用:
List<Car> cars = session.createCriteria(Car.class)
.add(Restrictions.eq("color", "black"))
.add(Restrictions.eq("id.model", "batmobile"))
.createAlias("id.owner", "o")
.add(Restrictions.eq("o.firstname", "Bruce"))
.list();
Result : 结果:
Hibernate: select this_.model as model1_0_0_, this_.owner_id as owner_id3_0_0_, this_.color as color2_0_0_ from Car this_ where this_.color=? and this_.model=? and o1_.firstname=?
ERROR: Unknown column 'o1_.firstname' in 'where clause'
What is the right way to obtain what I want ? 什么是获得我想要的正确方法?
update 更新
I tried in hql : 我在hql中尝试过:
String hql = "FROM Car as car where car.color = :color and car.id.model = :model and car.id.owner.firstname = :firstname";
Query query = em.createQuery(hql);
query.setParameter("color", "black");
query.setParameter("model", "batmobile");
query.setParameter("firstname", "Bruce");
List<Car> cars = query.getResultList();
It works but is there a way to do this with criteria ? 它有效但是有没有办法用标准来做到这一点?
You forgot to add the @Column
annotation on top of the firstname and lastname fields (and the color field in Car). 您忘记在名字和姓氏字段(以及Car中的颜色字段)之上添加
@Column
注释。 In hibernate if a field is not annotated, it doesn't recognize it as a database field. 在休眠状态下,如果未注释某个字段,则不会将其识别为数据库字段。 This page should give you a good idea about how to set up your model objects .
此页面可以让您了解如何设置模型对象 。
NOTE: You can have the column annotation over the getters and be fine, but you didn't show the getters. 注意:您可以将列注释放在getter上并且没问题,但是您没有显示getter。 Either place is fine.
这两个地方都没关系。
Look at what HQL is spitting back out, specifically the statement (formated for easier reading): 看看HQL正在吐出什么,特别是声明(为便于阅读而编写):
select
this_.model as model1_0_0_,
this_.owner_id as owner_id3_0_0_,
this_.color as color2_0_0_
from Car this_
where
this_.color=?
and this_.model=?
and o1_.firstname=?
It looks like hibernate is translating the field "id.owner" to "o" as your alias told it to to, but for some reason it's not writing down that "id.owner=o" as intended. 看起来hibernate正在将字段“id.owner”翻译为“o”,因为你的别名告诉它,但由于某种原因,它并没有按照预期写下“id.owner = o”。 You may want to do some research into why it may be doing that.
您可能想要研究它为什么这样做。
As per https://hibernate.atlassian.net/browse/HHH-4591 there is a workaround. 根据https://hibernate.atlassian.net/browse/HHH-4591,有一种解决方法。
You have to copy the needed relation-property of the @EmbeddedId
( owner
in this case) to the main entity ( Car
in this case) with insertable = false, updatable = false
as follows 您必须将
@EmbeddedId
(在本例中为owner
)所需的relation-property复制到主实体(在本例中为Car
), insertable = false, updatable = false
,如下所示
@Entity
public class Car {
@EmbeddedId
private Id id = new Id();
private String color;
@ManyToOne
@JoinColumn(name = "column_name", insertable = false, updatable = false)
private Owner owner;
@Embeddable
public static class Id implements Serializable {
private static final long serialVersionUID = -8141132005371636607L;
@ManyToOne
private Owner owner;
private String model;
// getters and setters...
// equals and hashcode methods
}
// getters and setters...
}
Then just create directly the alias instead of using the composite id property 然后直接创建别名而不是使用复合id属性
List<Car> cars = session.createCriteria(Car.class)
.add(Restrictions.eq("color", "black"))
.add(Restrictions.eq("id.model", "batmobile"))
.createAlias("owner", "o")
.add(Restrictions.eq("o.firstname", "Bruce"))
.list();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.