簡體   English   中英

Java - 標准 API - 單向 OneToMany

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM