Java-标准API-单向OneToMany

Java-标准API-单向OneToMany,java,spring,hibernate,criteria-api,Java,Spring,Hibernate,Criteria Api,我正试图通过CriteriaAPI从流程表中的人员处获取许可证号。 基本上是从Process->Person->License 然而,Person表与表许可证具有单向的OneToMany关系 因此,我有以下实体: @Entity @Table(name = "Process") public class Process { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private I

我正试图通过CriteriaAPI从流程表中的人员处获取许可证号。 基本上是从
Process->Person->License

然而,Person表与表许可证具有单向的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;
}

我试过加入:

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=entityManager.getCriteriaBuilder();
final CriteriaQuery criteria=builder.createQuery(Process.class);
最终根rootSelect=criteria.from(Process.class);
//我真的不知道如何加入rootSelect(进程表),与许可证表。。。让餐桌上的人在中间。。
Join personJoin=rootSelect.Join(“人”);
Join-licenseJoin=rootSelect.Join(“个人”);
并考虑使用子查询:

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")));
final CriteriaBuilder=entityManager.getCriteriaBuilder();
final CriteriaQuery criteria=builder.createQuery(Process.class);
最终根rootSelect=criteria.from(Process.class);
Subquery sub=criteria.Subquery(String.class);
Root subRoot=sub.from(License.class);
//如何仅选择下面的“许可证号码”字段?
子菜单选择(子菜单);
sub.where(builder.equal(rootSelect.get(“person”).get(“id”)、subRoot.get(“person”));
我需要一个过滤器的许可证号码(在哪里)


考虑到我的根表是进程,执行此类筛选的最佳方法是什么?

严格来说,您不必使用许可证加入进程表,您必须使用Person和Person with license加入进程,如下所示:

Join<Process, Person> personJoin = rootSelect.join("person",JoinType.INNER);
Join<Person, License> licenseJoin = personJoin.join("licenses",JoinType.INNER);
Join<Process, Person> personJoin = rootSelect.join("person",JoinType.INNER);
Join<Person, License> licenseJoin = personJoin.join("licenses",JoinType.INNER);
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));