0

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;
    }

    // ...
}

人:

@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;
    }

    // ...
}

従業員エンティティ:

@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...
}

次に、上記のクエリを使用して、正式な名前、たとえば「Doe、John」で従業員を見つけようとしました。

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

ただし、これにより、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:

どうしたの?JPQLで「人工」プロパティ(ここではWHERE句)を使用することは禁止されていますか?ここの前提は何ですか?

大文字と小文字の区別とスペルを何度も確認しましたが、運が悪かったです。

4

1 に答える 1

2

クラスにはformalNameのマッピングがないため、クエリで使用することはできません。クエリ内のマッピングにのみアクセスできます。とにかくデータベースにFormalNameがないので、どのように使用できるかわかりません。

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"

OrganizationalUnitクラスのフィールドにはアノテーションが付いているため、デフォルトのマッピングはフィールドのみになります。これは、PersonのgetNameが名前をthis.firstName + "" + this.lastNameとして定義しているにもかかわらず、テーブルにfirstName、LastName、およびNameフィールドが含まれることを意味します。PersonのfirstName/lastNameフィールドを削除し、代わりにnameフィールドを処理することをお勧めします。または、OrganizationalUnitからnameフィールドを削除して、サブクラスクラスにget/setnameアクセサーを独自の方法で処理させることができます。

于 2012-11-22T16:57:43.793 に答える