2012-11-22 4 views
0

У меня есть объект Employee, который наследует от человека и OrganizationalUnit:JPQL: неизвестное состояние или поля ассоциации (EclipseLink)

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

    // ... 
} 

сотрудников:

Затем я попытался найти сотрудника по его формальному имени, например. "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? Какие здесь помещения?

Я проверил капитализацию и орфографию много раз, мне не повезло.

ответ

2

У вашего класса нет сопоставления для формального имени, поэтому он не может использоваться в запросе. Доступ к сопоставлениям возможен только в ваших запросах. В любом случае в базе данных нет 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 имеет аннотации на своих полях, поэтому только поля будут иметь сопоставления по умолчанию. Это означает, что в вашей таблице будут поля firstName, LastName AND Name, несмотря на getName в Person, определяющие имя как this.firstName + "" + this.lastName. Я бы рекомендовал удалить поля firstName/lastName в Person и вместо этого иметь дело с полем имени или вы можете удалить поле имени из OrganizationalUnit и позволить классам подклассов обрабатывать get/setname accessors по-своему.

Смежные вопросы