org.hibernate.AnnotationException:referencedColumnNames(P0,P1,P2)...未映射到单个属性

时间:2012-03-02 18:26:13

标签: sql-server spring hibernate java-6

我正在使用MS SQL服务器,Spring 3,Hibernate JPA 2.0。 我有四个表Level0,Level1,level2和Level3。 Level0的id为P0作为主键。 Level1有一个compsoite主键,P0从level0作为FK和P1。 Level2有一个复合键Level0.P0,Level1.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有Level1s的集合,Level1有Level2s的集合,依此类推。 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) 引用Level2的Level3.level2未映射到单个属性。

Level2有2个外键及其自己的字段,3表示复合主键。这很有效。但是Level3有3个外键。事实并非如此。

有人可以帮我吗?感谢。

1 个答案:

答案 0 :(得分: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...
}

有了这个,我的Hibernate能够解决复合关系而没有出现这个错误。

P.S。在我看来,您没有正确映射主要复合键(“复合主键使用嵌入式类作为主键表示”),请查看http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/#d0e2177