【问题标题】:org.hibernate.AnnotationException: referencedColumnNames(P0, P1, P2)... not mapped to a single propertyorg.hibernate.AnnotationException: referencedColumnNames(P0, P1, P2)... 未映射到单个属性
【发布时间】:2012-03-02 18:26:13
【问题描述】:

我正在使用 MS SQL 服务器、Spring 3、Hibernate JPA 2.0。 我有四个表 Level0、Level1、level2 和 Level3。 Level0 有一个 id P0 作为主键。 Level1 有一个复合主键,其中来自 level0 的 P0 作为 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 有 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) of Level3.level2 引用 Level2 未映射到单个属性。

Level2 有 2 个外键和它自己的字段,这 3 个构成复合主键。那行得通。但是 Level3 有 3 个外键。但事实并非如此。

有人可以帮我解决这个问题吗?谢谢。

【问题讨论】:

    标签: sql-server spring hibernate java-6


    【解决方案1】:

    这可能会有所帮助,但我不确定这是否是正确的做法:

    我遇到过类似的情况,它给出了相同的错误,但是我的复合 FK 没有与主键绑定,而是与逻辑唯一键绑定。我通过为关系的每个组件创建额外的字段来解决这个问题。

    即在您的 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 能够解决复合关系而不会出现该错误。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-27
      • 1970-01-01
      • 1970-01-01
      • 2014-04-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多