2011-11-10 70 views
2

我想了解如何在JPQL中執行(簡單)連接。我有兩個表/實體:父母和孩子。JPA:PersistenceException「未知狀態或關聯字段」

@Entity 
@Table(name = "Parent") 
@NamedQueries({ 
    @NamedQuery(name = "Parent.findByStatus", query = "SELECT p FROM Parent p WHERE p.status = :status")}) 
public class Parent 
{ 
    private String parentId; 
    private Set<Child> children; 
    private String status; 

    public Parent() 
    { 
     // empty constructor 
    } 

    @Id 
    @Column(name = "PARENT_ID") 
    public String getParentId() 
    { 
     return parentId; 
    } 

    public void setParentId(String parentId) 
    { 
     this.parentId= parentId; 
    } 

    // bi-directional many-to-one association to Child 
    @OneToMany(mappedBy = "parent") 
    public Set<Child> getChildren() 
    { 
     return children; 
    } 

    public void setChildre(Set<Child> children) 
    { 
     this.children= children; 
    } 
    @Column(name = "STATUS") 
    public String getStatus() 
    { 
     return status; 
    } 

    public void setStatus(String status) 
    { 
     this.status = status; 
    } 
} 

@Entity 
@NamedQueries({ 
     @NamedQuery(name = "Child.findByStatus", query = "SELECT c FROM Child c WHERE c.status = :status"), 
     @NamedQuery(name = "Child.findByParentId", query = "SELECT c FROM Child c JOIN c.parent p WHERE p.parentId = :parentId"), 
     @NamedQuery(name = "Child.findByParentIdAndStatus", query = "SELECT c FROM Child c JOIN c.parent p WHERE p.parentId = :parentId AND c.status = :status") }) 
public class Child 
{ 
    private childId id; 
    private String status; 
    private Parent parent; 

    public Child() 
    { 
     // empty constructor 
    } 

    @Id 
    @Column(name = "CHILD_ID") 
    public String getChildId() 
    { 
     return childId; 
    } 

    public void setChildId(String childId) 
    { 
     this.childId= childId; 
    } 

    // bi-directional many-to-one association to Parent 
    @ManyToOne 
    @JoinColumn(name = "PARENT_ID") 
    public Parent getParent() 
    { 
     return parent; 
    } 

    public void setParent(Parent parent) 
    { 
     this.parent= parent; 
    } 

    @Column(name = "STATUS") 
    public String getStatus() 
    { 
     return status; 
    } 

    public void setStatus(String status) 
    { 
     this.status = status; 
    } 
} 

但是這將導致以下異常:

Caused by: javax.persistence.PersistenceException: Exception [EclipseLink-8030] (Eclipse Persistence Services - 2.3.0.v20110604-r9504): org.eclipse.persistence.exceptions.JPQLException 
Exception Description: Error compiling the query [Child.findByParentId: SELECT c FROM Child c JOIN c.parent p WHERE p.parentId = :parentId], line 1, column 47: unknown state or association field [parentId] of class [my.model.Parent]. 

這是我的理解是JPQL遍歷對象模型上的連接。因此,在查詢中:

SELECT c FROM Child c JOIN c.parent p WHERE p.parentId = :parentId 

p是與子對象關聯的提取的父對象。如果這是正確的,那麼爲什麼我得到錯誤?父對象有一個parentId字段,所以應該沒問題,是嗎?

回答

1

您的JPQL看起來有效。檢查你是否正確編譯了你的代碼,(你最近是否重命名了這個字段?)。

查詢任何其他字段是否工作?如果將該字段重命名爲id,該怎麼辦?

+0

我使用Maven來完成我的構建。實體類被構建到一個jar庫中,供我的測試servlet使用。我已經清理並重建了兩個項目的倍數包括從repo手動清除實體庫,以確保它是servlet戰爭中使用的最新實體庫。我正在部署到GlassFish v3.1.1,並試圖取消部署和重新部署戰爭。所以,我非常確定代碼是正確編譯的,這是非常令人沮喪的,因爲我所見過的所有關於JPQL的例子都表明我的查詢是正確的 – sdoca

+0

如果我註釋掉Child中有連接到Parent的查詢,我可以成功執行「Parent.findByStatus」查詢。所以,我的連接肯定有問題。嘆息.... – sdoca

+0

也請嘗試parentID – James

0

可以使用兒童領域實現這一目標,

from Child c where c.parent.id = :parent_id 

或只是如果你手頭上有,而不僅僅是ID的參考親。

from Child c where c.parent = :parent 

hibernate會找出連接本身。

+0

感謝您的建議。我沒有對父對象的引用,所以不能使用第二個。第一個導致相同的錯誤。 (順便說一句,我沒有使用Hibernate,但EclipseLink。 – sdoca