【问题标题】:Using an @Embeddable entity in a JPA CriteriaQuery在 JPA CriteriaQuery 中使用 @Embeddable 实体
【发布时间】:2015-05-15 09:37:16
【问题描述】:

假设我有以下示例实体 - 一个是 @Embeddable,嵌入另一个 @Entity

@Embeddable
public class ContactInfoEntity {

    @Column
    private String phone;

    @Column
    private String zipCode;
}

@Entity
@Table(name = "EMPLOYEE")
public class EmployeeEntity {

    @Id
    @Column(name = "EMPLOYEE_ID")
    private Long employeeId;

    @Embedded
    @AttributeOverrides({
        @AttributeOverride(name = "phone",
                           column = @Column(name = "EMPLOYEE_PHONE")),
        @AttributeOverride(name = "zipCode",
                           column = @Column(name = "EMPLOYEE_ZIP_CODE"))
    })
    private ContactInfoEntity employeeContactInfo;
}

由 openjpa-maven-plugin 生成的元模型类仅包含一个 employeeContactInfo 变量,而不包括 @AttributeOverride 列。

现在假设我想这样做:

选择EMPLOYEE_IDEMPLOYEE_PHONE,其中EMPLOYEE_ZIP_CODE 等于“123456”

如何将其创建为 CriteriaQuery

CriteriaBuilder cb = entityManager.getCriteriaBuilder();

CriteriaQuery<String> qDef = cb.createQuery(String.class);
Root<EmployeeEntity> e = qDef.from(EmployeeEntity.class);
qDef.select(e.get(EmployeeEntity_.employeeId),
            e.get(????))
    .where(cb.equal(e.get(????), "123456"));

return entityManager.createQuery(qDef).getResultList();

【问题讨论】:

  • ContactInfoEntityEmployeeEntity 有什么关系? ResourceNodeEntity不应该换成ContactInfoEntity吗?
  • @wypieprz 假装你从未见过 :) 复制粘贴错字泄漏到示例代码中。固定!

标签: java jpa criteria openjpa criteria-api


【解决方案1】:

一个示例方法可能如下所示:

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Object[]> qDef = cb.createQuery(Object[].class);
Root<EmployeeEntity> e = qDef.from(EmployeeEntity.class);
qDef.multiselect(
     e.get(EmployeeEntity_.employeeId),
     e.get(EmployeeEntity_.employeeContactInfo).get(ContactInfoEntity_.phone));
qDef.where(
     cb.equal(
        e.get(EmployeeEntity_.employeeContactInfo).get(ContactInfoEntity_.zipCode), 
        cb.literal("123456")));

List<Object[]> objects = em.createQuery(qDef).getResultList();
for (Object[] element : objects) {
    System.out.format("%d %s", element[0], element[1]);
}

根据您的偏好,您可能还希望获得如下查询结果:

  • 构造函数表达式

    public class EmployeeEntityResult {
        private int id;
        private String phone;
    
        public EmployeeEntityResult(int id, String phone) {
            this.id = id;
            this.phone = phone;
        }
        ...
    }
    
    CriteriaQuery<EmployeeEntityResult> cq = cb.createQuery(EmployeeEntityResult.class);
    ...
    List<EmployeeEntityResult> result = em.createQuery(cq).getResultList();
    for (EmployeeEntityResult element : result) {
        System.out.format("%d %s", element.getId(), element.getPhone());
    }
    
  • 元组

    CriteriaQuery<Tuple> cq = cb.createTupleQuery();
    ...
    cq.select(
       cb.tuple(
          e.get(EmployeeEntity_.employeeId)
           .alias("id"),
          e.get(EmployeeEntity_.employeeContactInfo).get(ContactInfoEntity_.phone)
           .alias("phone")));
    ...
    List<Tuple> tuple = em.createQuery(cq).getResultList();
    for (Tuple element : tuple) {
        System.out.format("%d %s", element.get("id"), element.get("phone"));
    }
    

JPQL 查询如下所示:

SELECT e.id, e.employeeContactInfo.phone
FROM EmployeeEntity e
WHERE e.employeeContactInfo.zipCode = '123456'

【讨论】:

    猜你喜欢
    • 2020-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-07
    • 2018-12-08
    • 2011-04-12
    • 1970-01-01
    • 2018-04-13
    相关资源
    最近更新 更多