[英]Java - Criteria API - Unidirectional OneToMany
我正在嘗試通過標准 API 從流程表中的人員那里獲取許可證號。 基本上來自Process -> Person -> License
但是,Person 表與表 License 具有單向 OneToMany 關系。
所以我有以下實體:
@Entity
@Table(name = "Process")
public class Process {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "person_id")
Person person;
}
@Entity
@Table(name = "Person")
public class Person {
@Id
@Column(name = "id",columnDefinition="INTEGER")
@GeneratedValue(strategy = GenerationType.IDENTITY)
Integer id;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "person")
List<License> licenses;
}
@Entity
@Table(name = "License")
public class License {
@Id
@Column(name = "id",columnDefinition="INTEGER")
@GeneratedValue(strategy = GenerationType.IDENTITY)
Integer id;
@JoinColumn(name = "person_id")
@ManyToOne(fetch = FetchType.LAZY)
Person person;
String licenseNumber;
}
在本機查詢中,我想要完成的結果是:
select lic.license_number, * from Process process
left join Person p on process.person_id = p.id
left join License lic on lic.person_id = p.id;
我試過加入:
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
final CriteriaQuery<Process> criteria = builder.createQuery(Process.class);
final Root<Process> rootSelect = criteria.from(Process.class);
//I don't really know how to join rootSelect (Process table), with License table... having the table Person in middle..
Join<Process, Person> personJoin = rootSelect.join("person");
Join<License, Person> licenseJoin = rootSelect.join("person");
並且還考慮使用子查詢:
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
final CriteriaQuery<Process> criteria = builder.createQuery(Process.class);
final Root<Process> rootSelect = criteria.from(Process.class);
Subquery sub = criteria.subquery(String.class);
Root subRoot = sub.from(License.class);
//How to select just the field 'license_number' below?
sub.select(subRoot);
sub.where(builder.equal(rootSelect.get("person").get("id"), subRoot.get("person")));
最后,我將需要 license_number 用於過濾器(在哪里)。
考慮到我的根表是 Process,執行這種過濾器的最佳方法是什么?
嚴格來說,您不必使用許可證加入 Process 表,您必須將 Process 加入 Person 和 Person with License,如下所示:
Join<Process, Person> personJoin = rootSelect.join("person",JoinType.INNER);
Join<Person, License> licenseJoin = personJoin.join("licenses",JoinType.INNER);
建議使用元模型和實體,它們的連接如下(元模型由 EntityName_ 表示):
Join<Process, Person> personJoin = rootSelect.join(Process_.person,JoinType.INNER);
Join<Person, License> licenseJoin = personJoin.join(Person_.licences,JoinType.INNER);
對我來說,最明顯的好處是您可以自動完成元模型的屬性,放置字符串會增加我們出錯的機會。
我們添加過濾條件
cq.where(cb.equal(licenceseJoin.get("licenseNumber"),LICENSE_NUMBER));
//cq.where(cb.equal(licenceseJoin.get(License_.licenseNumber),LICENSE_NUMBER));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.