JPA:使用criteriabuilder查找实体:属性名称与注释不同吗?

时间:2019-09-11 18:35:17

标签: java mysql jpa criteria

我有一个包含员工信息的mysql数据库,每个员工都有一个技术ID作为主键。在MySQL中选择符合条件的行,我只能使用以下语句(有效)

SELECT * FROM database_test.employee WHERE fist_name='First1';

在Java中,我还可以将其用作本机语句来获取我想要的东西(有效):

        List<EmployeeEntity2> objects = m_em.createNativeQuery(
            "SELECT * database_test.employee WHERE first_name='First1'",
            EmployeeEntity2.class).getResultList();

但是,我想使用Criteriabuilder来获得相同的结果,并稍后将其推广用于多个columnName = columnEntry选择。

public List<EmployeeEntity2> testNoParameter() {

    //Based on https://www.objectdb.com/java/jpa/query/criteria

    CriteriaBuilder cb = m_em.getCriteriaBuilder();

    CriteriaQuery<EmployeeEntity2> q = cb.createQuery(EmployeeEntity2.class);
    Root<EmployeeEntity2> c = q.from(EmployeeEntity2.class);
    ParameterExpression<String> p = cb.parameter(String.class);
    //Works
    //q.select(c).where(cb.equal(c.get("firstName"), p));
    //Won't work
    q.select(c).where(cb.equal(c.get("first_name"), p));        
    TypedQuery<EmployeeEntity2> query = m_em.createQuery(q);

    query.setParameter(p, "First1");
    List<EmployeeEntity2> results = query.getResultList();
    return results;
}

使用“ fist_name”(来自实体的列名称注释)将产生以下java.lang.IllegalArgumentException与:

    Unable to locate Attribute  with the the given name [first_name] on this ManagedType [xx.xxx.database.EmployeeEntity2]

EmployeeEntity2具有“ fist_name”注释:

@Column(name = "first_name", nullable = false)
@Override
public String getFirstName() {
    return super.getFirstName();
}

因此,“ first_name”应该存在,但是(经过一些调试)我发现由于某些原因,期望的属性不是“ firstName”,而是我没有定义/注释的名称,因此它来自何处,以及如何我使用数据库中实际定义的列名(column =“ first_name”)?

1 个答案:

答案 0 :(得分:1)

您应使用实体的属性名称(而非列名称)在条件构建器中使用它,而不是

 q.select(c).where(cb.equal(c.get("first_name"), p));  

使用

 q.select(c).where(cb.equal(c.get("firstName"), p));  

CriteriaBuilder与RDBMS模式无关,因此您使用模型(实体),而不使用模式(表名称等)。

在JPA中,通常不使用SQL,而使用JPQL。在JPQL中,等效的SQL类似于

"SELECT e FROM EmployeEntity2 e WHERE e.firstName='First1'"

以后CriteriaQuery树和JPQL字符串都向下转换为同一查询树(不记得名称),因此它们都必须遵守完全相同的规则。