试图围绕 Criteria API(哎哟)。我有 3 个类:Devices、Offices 和 SiteCodes。全部加入
设备.java
private Offices office;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "office_id")
public Offices getOffice() {
return office;
}
public void setOffice(Offices office) {
this.office = office;
}
办公室.java:
private List<SiteCodes> siteCodes;
@ManyToMany(cascade = CascadeType.PERSIST)
@JoinTable(name = "site_code_map", joinColumns = {
@JoinColumn(name = "office_id") }, inverseJoinColumns = {
@JoinColumn(name = "site_code_id") })
@OrderBy("siteCode ASC")
public List<SiteCodes> getSiteCodes() {
return this.siteCodes;
}
public void setSiteCodes(List<SiteCodes> siteCodes) {
this.siteCodes = siteCodes;
}
站点代码.java
private id;
private String siteCode;
<getters and setters>
我正在尝试使用站点代码查找 Devices.devId。sql 看起来像这样:
SELECT d.dev_id
FROM devices d, offices o, site_code_map s, site_codes ss
WHERE d.office_id=o.office_id
AND s.office_id=o.office_id
AND s.site_code_id=ss.site_code_id
AND ss.`site_code`='0S21'
我正在尝试使用连接,但不太了解如何操作。我得到以下编译:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Integer> cq = cb.createQuery(Integer.class);
Root<Devices> d = cq.from(Devices.class);
Join<Devices, Offices> join1 = d.join(Devices_.office);
ListJoin<Offices,SiteCodes> join2 = join1.join(Offices_.siteCodes);
我不知道如何使用 join2 所以我使用了 join1 和这样的路径
ParameterExpression<SiteCodes> p = cb.parameter(SiteCodes.class, "sitecode");
Predicate pr = cb.isMember(p, join1.get(Offices_.siteCodes));
cq.where(pr);
最终
TypedQuery<Integer> tq = em.createQuery(cq);
<set parameter here to a SiteCode object>
List<Integer> idList = tq.getResultList();
它产生如下的sql。该子查询不属于 - 我希望它使用连接,并且无论如何它都会抛出 TransientObjectException ,即使我所做的只是选择:
select
devices0_.dev_id as col_0_0_
from
devices devices0_
inner join
offices offices1_
on devices0_.office_id=offices1_.office_id
inner join
site_code_map sitecodes2_
on offices1_.office_id=sitecodes2_.office_id
inner join
site_codes sitecodes3_
on sitecodes2_.site_code_id=sitecodes3_.site_code_id
where
? in (
select
sitecodes4_.site_code_id
from
site_code_map sitecodes4_
where
offices1_.office_id=sitecodes4_.office_id
无论如何它也会抛出这个错误(不包括整个堆栈跟踪,除非有人想看到它):
Caused by: org.hibernate.TransientObjectException: object references an
unsaved transient instance - save the transient instance before
flushing: dne.nmst.dac.model.SiteCodes
这让我很困惑,因为我没有做任何保存,只是选择。
我怎样才能让它工作?我希望正确构建标准,当然不会发生错误。