【问题标题】:JPA Critera API Join 3 Tables get 1 TypeJPA Criteria API Join 3 Tables get 1 Type
【发布时间】:2017-03-01 07:40:58
【问题描述】:

我正在尝试使用 JPA Critera API 连接 3 个表,并将结果作为关系表以外的类型列表获取。

实体是:

| Employee |   | Contract |   | Company |
|----------|   |----------|   |---------|
| id       |   | Company  |   | id      |
| age      |   | Employee |   | name    |
  • 合同是公司与员工之间的关系
  • 一名员工可能属于一家或多家公司
  • 一家公司有一名或多名员工

我现在尝试让为 A 公司工作的所有员工都像这样:

    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Contract> query = cb.createQuery(Contract.class);

    Root<Contract> contracts = query.from(Contract.class);
    Join<Contract, Company> companyJoin = contracts.join("company");
    Join<Contract, Employee> employeeJoin = contracts.join("employee");

    List<Predicate> conditions = new ArrayList<Predicate>();
    conditions.add(cb.equal(companyJoin.get("name"), "Company A"));

    TypedQuery<Practice> typedQuery = em.createQuery(query
            .select(contracts)
            .where(conditions.toArray(new Predicate[conditions.size()]))
    );

    typedQuery.getResultList();

这给了我一份与在“A 公司”工作的员工签订的合同列表。

如何编写查询以获取员工列表而不是合同?

【问题讨论】:

  • 为什么不使用 JPQL?

标签: java jpa criteria-api


【解决方案1】:

从员工的Root 开始并创建一个连接链:

CriteriaQuery<Employee> query = cb.createQuery(Employee.class);
Root<Employee> employee = query.from(Employee.class);
Join<Employee, Contract> contractJoin = employee.join("contracts"); // assuming that Employee has a collection property named contracts
Join<Contract, Company> companyJoin = contractJoin.join("company");

这是正确的 Awnser,并添加了以下内容:

类型“Employee”和“Company”必须有一个字段“companies”/“employees”和@JoinTable 注释,如下所示:

员工:

...
@OneToMany
@JoinTable(name="Contract" ...)
private List<Company> companies;
...

公司

...
@OneToMany
@JoinTable(name="Contract" ...)
private List<Employee> employees;
...

“@JoinTable”注解可防止休眠自行创建关系表。
有关详细信息,请参阅 cmets。

【讨论】:

  • 这就是问题所在,Employee 类型没有“contracts”字段。
  • 为什么不能像所有 JPA 示例中关于 OneToMany 和 ManyToOne 关系的那样添加它?
  • 如果我将字段“@OneToMany contracts”添加到 Employee,hibernate 会在我的数据库中添加另一个表。是不是有点多余,因为可以从 Contracts 表本身读取信息?
  • 你是对的,你不需要其他表。我不是 Hibernate 的粉丝,我从不让它创建或更新我的数据库。您应该能够在不让 Hibernate 添加新表的情况下定义正确的关系。但这似乎属于一个新问题...
  • 允许/阻止 HIbernate 创建数据库表的设置:Does Hibernate create tables in the database automatically。此外,如果 Hibernate 想要创建一个新表,您可能需要将名称与 @Table 注释的 name 属性映射,并检查关系是否正确定义,如图所示 here
猜你喜欢
  • 2013-06-21
  • 2016-03-09
  • 2021-12-22
  • 1970-01-01
  • 1970-01-01
  • 2022-12-02
  • 2021-10-13
  • 2012-02-02
  • 2014-08-28
相关资源
最近更新 更多