我想找一个使用critera的实体,它限制第二个实体的属性值,该实体是我第一个实体的嵌入式id的成员。
第一个实体:
@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...
}
第二实体:
@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...
}
在这个例子中,我想获得一辆颜色为“黑色&#39;”型号&#39; batmobile&#39;和老板的名字&#39;布鲁斯&#39; (哎呀......剧透;))
我尝试做类似的事情,但它没有工作:
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();
结果:
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'
获得我想要的东西的正确方法是什么?
更新
我试过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();
它有效,但有没有办法用标准来做到这一点?
答案 0 :(得分:0)
您忘记在firstname和lastname字段(以及Car中的颜色字段)之上添加@Column
注释。在休眠状态下,如果未注释某个字段,则不会将其识别为数据库字段。 This page should give you a good idea about how to set up your model objects
注意:您可以在getter上使用列注释并且没问题,但是您没有显示getter。这两个地方都没问题。
看看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=?
看起来hibernate正在将字段“id.owner”翻译为“o”,因为你的别名告诉它,但由于某种原因,它并没有按照预期写下“id.owner = o”。您可能想要研究它为什么这样做。
答案 1 :(得分:0)
根据https://hibernate.atlassian.net/browse/HHH-4591,有一种解决方法。
您必须将@EmbeddedId
(在这种情况下为owner
)所需的关系属性复制到主要实体(在本例中为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...
}
然后直接创建别名而不是使用复合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();