2012-03-02 63 views
1

我正在使用MS SQL Server,Spring 3,Hibernate JPA 2.0。 我有四個表格Level0,Level1,Level2和Level3。 Level0有一個ID作爲主鍵。 Level1有一個compsoite主鍵,其中level0的P0作爲FK和P1。 Level2有一個組合鍵Level0.P0,Level1.P1和P2。等等。 表格定義如下。org.hibernate.AnnotationException:referencedColumnNames(P0,P1,P2)...未映射到單個屬性

CREATE TABLE Level0 
(
    P0 integer NOT NULL, 
    Level0_name varchar(50) NOT NULL, 
    PRIMARY KEY (P0) 
); 

CREATE TABLE Level1 
(
    P0 integer NOT NULL, 
    P1 varchar(10) NOT NULL, 
    Level1_Name varchar(60), 
    PRIMARY KEY (P0, P1) 
); 
ALTER TABLE Level1 ADD CONSTRAINT FK_Level1 FOREIGN KEY (P0) REFERENCES Level0(P0); 

CREATE TABLE Level2 
(
    P0 integer NOT NULL, 
    P1 varchar(10) NOT NULL, 
    P2 varchar(10) NOT NULL, 
    Level2_Name varchar(20), 
    PRIMARY KEY (P0, P1, P2) 

); 
ALTER TABLE Level2 ADD CONSTRAINT FK_Level2 
FOREIGN KEY (P0, P1) REFERENCES Level1(P0, P1); 

CREATE TABLE Level3 
(
    P0 integer NOT NULL, 
    P1 varchar(10) NOT NULL, 
    P2 varchar(10) NOT NULL, 
    P3 varchar(10) NOT NULL, 
    Level3_Name varchar(20) NOT NULL, 
    PRIMARY KEY (P0, P1, P2, P3) 
); 
ALTER TABLE Level3 ADD CONSTRAINT FK_Level3 
FOREIGN KEY (P0, P1, P2) REFERENCES Level2(P0, P1, P2); 

我對每個表都有相應的Java類。所以Level0具有Level1的集合,Level1具有Level2的集合等等。 Level3包含Level2對象,Level2包含Level1對象等。這是Level1和Level2的Java類。

@Entity 
@Table(name="Level1") 
public class Level1 extends DomainObject 
{ 
    private String p1; 
    private Level0 level0; 
    private String name; 
    private List<Level2> level2s = new ArrayList<Level2>(); 

    @Id 
    @NotNull 
    @Column(name="P1") 
    public String getP1() 
    { 
     return(p1); 
    } 

    @NotNull 
    @ManyToOne(cascade={CascadeType.DETACH, 
       CascadeType.MERGE, 
       CascadeType.PERSIST, 
       CascadeType.REFRESH}) 
    @JoinColumn(name="P0", 
      referencedColumnName="P0") 
    public Level0 getLevel0() 
    { 
     return(level0); 
    } 

} 
---------------------------------------------------------- 
@Entity 
@Table(name="Level2") 
public class Level2 extends DomainObject 
{ 
    private String p2; 
    private Level1 level1; 
    private String name; 
    private List<Level3> level3s = new ArrayList<Level3>(); 

    @Id 
    @NotNull 
    @Column(name="P2") 
    public String getP2() 
    { return(p2); 
    } 

    @ManyToOne(fetch=FetchType.LAZY) 
    @JoinColumns({ 
     @JoinColumn(name="P0", referencedColumnName="P0"), 
     @JoinColumn(name="P1", referencedColumnName="P1") 
    }) 
    public Level1 getLevel1() 
    { return(level1); 
    } 

    @NotNull 
    @Column(name="Level2_Name") 
    public String getName() 
    { return(name); 
    } 

    @OneToMany(orphanRemoval=true, 
    cascade=CascadeType.ALL, 
    mappedBy="level2", 
    fetch = FetchType.LAZY) 
    public List<Level3> getLevel3s() 
    { 
    return(level3s); 
    } 
} 

Level0,Level1和Level2之間的這些關係很好。代碼正常工作。 當我添加Level3類時,它會引發錯誤。這是Level3的樣子。

public class Level3 extends DomainObject 
{ 
    private String p3; 
    private Level2 level2; 
    private String name; 


    @Id 
    @NotNull 
    @Column(name="P3") 
    public String getP3() 
    { 
     return(p3); 
    } 

    @ManyToOne(fetch=FetchType.LAZY) 
    @JoinColumns({ 
     @JoinColumn(name="P0", referencedColumnName="P0"), 
     @JoinColumn(name="P1", referencedColumnName="P1"), 
     @JoinColumn(name="P2", referencedColumnName="P2") 
    }) 
    public Level2 getLevel2() 
    { 
     return(level2); 
    } 

    @NotNull 
    @Column(name="Level3_Name") 
    public String getName() 
    { 
     return(name); 
    } 

} 

我得到以下錯誤: 引起:org.hibernate.AnnotationException:referencedColumnNames(P0,P1,P2) Level3.level2引用級別2的沒有被映射到一個單一的財產。

Level2有2個外鍵和它自己的字段,這3個組合主鍵。那是有效的。但Level3有3個外鍵。而那不。

有人可以幫助我嗎?謝謝。

回答

0

這可能會幫助,但我不知道這是做正確的方式:

我也有過類似的情況,讓出了同樣的錯誤,但在我的複合FK-S不會是綁定到一個主鍵,但邏輯唯一。我通過爲關係的每個組件創建額外的字段來解決這個問題。

即在Level2的你的情況,你會增加

@Entity 
@Table(name="Level2") 
public class Level2 extends DomainObject 
{ 
    @ManyToOne(fetch=FetchType.LAZY) 
    @JoinColumn(name="P0", referencedColumnName="P0", insertable=false, updatable=false) 
    private Level0 level0Dummy; 
    // getter setter... 
} 

有了這個我的休眠得以解決,而不該錯誤的複合關係。

p.s.在我看來,您沒有正確映射您的主要組合鍵(「複合主鍵使用嵌入類作爲主鍵表示形式」),請查看http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/#d0e2177