简体   繁体   English

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

[英]JPA: Using criteriabuilder to find entities: Attribute name different from annotation?

I have a mysql database with employee information, each employee has a technical id as primary key. 我有一个包含员工信息的mysql数据库,每个员工都有一个技术ID作为主键。 In MySQL to selcet row(s) matching criteria, i can just use to get the following statement (works) 在MySQL中选择匹配条件的行,我可以使用以下语句(有效)

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

In Java i can also use this as a native statement to get what i want (works): 在Java中,我也可以将此作为本机语句来获取我想要的东西(有效):

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

However, i wanted to use the Criteriabuilder to get the same result and later generalize it for multiple columnName=columnEntry selections. 但是,我想使用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;
}

Using "fist_name" - the column name annotation from the Entity - will yield the following java.lang.IllegalArgumentException with: 使用“ fist_name”(来自实体的列名称注释)将产生以下java.lang.IllegalArgumentException与:

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

EmployeeEntity2 has "fist_name" annotation: EmployeeEntity2具有“ fist_name”注释:

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

So "first_name" should exist, however (with some debugging) i found out that the attribute expected is for some reason "firstName" instead - which i have not defined/annotated - so where does it come from - and how can i use the column names actually defined in the database (column = "first_name")? 因此,“ first_name”应该存在,但是(通过一些调试)我发现由于某些原因,期望的属性不是“ firstName”,而是我没有定义/注释的名称,因此它来自何处,以及如何使用实际在数据库中定义的列名(column =“ first_name”)?

You should use property name of entity (not column name) to use it in criteria builder so instead of 您应该使用实体的属性名称(而不是列名称)在条件构建器中使用它,而不是

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

use 采用

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

CriteriaBuilder is RDBMS schema agnostic, so you use your model (entities), not schema (table names etc). CriteriaBuilder与RDBMS模式无关,因此您使用模型(实体),而不使用模式(表名称等)。

In JPA you dont normally use SQL but JPQL. 在JPA中,通常不使用SQL,而使用JPQL。 Equivalent of your SQL in JPQL would be something like 在JPQL中等效于您的SQL就像

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

Both CriteriaQuery tree and JPQL string are transformed down to the same query tree later on (can't remember the name), so they both must comply to the very same rules. CriteriaQuery树和JPQL字符串稍后都将转换为相同的查询树(不记得名称),因此它们都必须遵守完全相同的规则。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM