简体   繁体   English

JPQL:未知状态或关联字段(EclipseLink)

[英]JPQL: unknown state or association field (EclipseLink)

I have an Employee entity which inherits from Person and OrganizationalUnit: 我有一个继承自Person和OrganizationalUnit的Employee实体:

OrganizationalUnit: 组织单元:

@MappedSuperclass
public abstract class OrganizationalUnit implements Serializable
{
    @Id
    private Long id;

    @Basic( optional = false )
    private String name;

    public Long getId()
    {
        return this.id;
    }

    public void setId( Long id )
    {
        this.id = id;
    }

    public String getName()
    {
        return this.name;
    }

    public void setName( String name )
    {
        this.name = name;
    }

    // ...
}

Person: 人:

@MappedSuperclass
public abstract class Person extends OrganizationalUnit
{
    private String lastName;

    private String firstName;

    public String getLastName()
    {
        return this.lastName;
    }

    public void setLastName( String lastName )
    {
        this.lastName = lastName;
    }

    public String getFirstName()
    {
        return this.firstName;
    }

    public void setFirstName( String firstName )
    {
        this.firstName = firstName;
    }

    /**
     * Returns names of the form "John Doe".
     */
    @Override
    public String getName()
    {
        return this.firstName + " " + this.lastName;
    }

    @Override
    public void setName( String name )
    {
        throw new UnsupportedOperationException( "Name cannot be set explicitly!" );
    }

    /**
     * Returns names of the form "Doe, John".
     */
    public String getFormalName()
    {
        return this.lastName + ", " + this.firstName;
    }

    // ...
}

Employee entity: 员工实体:

@Entity
@Table( name = "EMPLOYEES" )
@AttributeOverrides
(
    {
        @AttributeOverride( name = "id", column = @Column( name = "EMPLOYEE_ID" ) ),
        @AttributeOverride( name = "name", column = @Column( name = "LASTNAME", insertable = false, updatable = false ) ),
        @AttributeOverride( name = "firstName", column = @Column( name = "FIRSTNAME" ) ),
        @AttributeOverride( name = "lastName", column = @Column( name = "LASTNAME" ) ),
    }
)
@NamedQueries
(
    {
        @NamedQuery( name  = "Employee.FIND_BY_FORMAL_NAME",
                     query = "SELECT emp " +
                             "FROM Employee emp " +
                             "WHERE emp.formalName = :formalName" )
    }
)
public class Employee extends Person
{
    @Column( name = "EMPLOYEE_NO" )
    private String nbr;

    // lots of other stuff...
}

I then attempted to find an employee by its formal name, eg "Doe, John" using the query above: 然后,我尝试使用上面的查询以正式名称找到一名雇员,例如“Doe,John”:

SELECT emp
FROM Employee emp
WHERE emp.formalName = :formalName

However, this gives me an exception on deploying to EclipseLink: 但是,这给我一个关于部署到EclipseLink的例外:

Exception while preparing the app : Exception [EclipseLink-8030] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.JPQLException
Exception Description: Error compiling the query [Employee.FIND_BY_CLIENT_AND_FORMAL_NAME: SELECT emp FROM Employee emp   JOIN FETCH emp.client   JOIN FETCH emp.unit WHERE emp.client.id = :clientId AND emp.formalName = :formalName], line 1, column 115: unknown state or association field [formalName] of class [de.bnext.core.common.entity.Employee].
Local Exception Stack: 
Exception [EclipseLink-8030] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.JPQLException
Exception Description: Error compiling the query [Employee.FIND_BY_CLIENT_AND_FORMAL_NAME: SELECT emp FROM Employee emp   JOIN FETCH emp.client   JOIN FETCH emp.unit WHERE emp.client.id = :clientId AND emp.formalName = :formalName], line 1, column 115: unknown state or association field [formalName] of class [de.bnext.core.common.entity.Employee].

Qs: QS:

What's wrong? 怎么了? Is it prohibited to use "artificial" properties in JPQL, here the WHERE clause? 是否禁止在JPQL中使用“人工”属性,这里是WHERE子句? What are the premises here? 这里的前提是什么?

I checked the capitalization and spelling many times, I'm out of luck. 我检查了大写和拼写很多次,我运气不好。

Your class doesn't have a mapping for formalName, so it cannot be used in a query. 您的类没有formalName的映射,因此不能在查询中使用它。 You can only accesss mappings within your queries. 您只能访问查询中的映射。 There is no FormalName in the database anyway, so I don't see how it could be used. 无论如何,数据库中没有FormalName,所以我看不出它是如何使用的。

Your query will need to be changed to access the first and last name the same way you attempt to do in the getFormalName code: 您需要更改您的查询以访问名字和姓氏,方法与尝试在getFormalName代码中进行操作相同:

"SELECT emp FROM Employee emp JOIN FETCH emp.client JOIN FETCH emp.unit WHERE emp.client.id = :clientId AND CONCAT(CONCAT(emp.lastName, ', '), emp.firstName) = :formalName"

Note that your OrganizationalUnit class has annotations on its fields, so only fields will have default mappings. 请注意,您的OrganizationalUnit类在其字段上有注释,因此只有字段具有默认映射。 This means your table will have firstName, LastName AND Name fields in it, despite getName in Person defining name as this.firstName + " " + this.lastName. 这意味着您的表中将包含firstName,LastName和Name字段,尽管getName in Person定义名称为this.firstName +“”+ this.lastName。 I'd recommend removing the firstName/lastName fields in Person and instead dealing with the name field, or you can remove the name field from OrganizationalUnit and let subclasses classes handle the get/setname accessors in their own way. 我建议删除Person中的firstName / lastName字段,而不是处理name字段,或者可以从OrganizationalUnit中删除name字段,让子类以自己的方式处理get / setname访问器。

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

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