2010-08-20 37 views
1

我有两个表部分和子部分。部分表具有通用字段,如id,name,desc等。SubPart表具有part_id,sub_part_id作为组合键。这两列都指的是零件表,并且每个零件都有一对多的映射,就像Part表中的每个part_id一样,在两个列的SubPart表中可以有多个条目。我在为SubPart表定义组合键时遇到问题。我尝试了嵌入式标签,但它不起作用。我该如何解决这个问题。非常感谢。休眠组合键是foreigen键到另一个表

部分表如下。

@Entity 
@Table(name="Part") 
public class Part { 

    @Id 
    @GeneratedValue 
    @Column(name="Part_Id") 
    private int id; 
    @Column(name="Part_Number") 
    private String partNumber; 
    @Column(name="Part_Name") 
    private String partName; 
} 

副部表

@Entity 
@Table(name="SubPart") 
public class SubPart { 
    // part and subPart combination is the compound key here. 
    @ManyToOne 
    @JoinColumn(name="Part_Id") 
    private Part part; 

    @ManyToOne 
    @JoinColumn(name="Sub_Part_Id") 
    private Part subPart; 

    @Column(name="Quantity") 
    private Integer quantity; 
} 

回答

6

你说

我在定义组合键的分部表

当你有一个复合主键,你必须定义类(一般问题一个静态的内部类),它定义了你的复合主键(只是一个建议:因为Hibernate使用代理,所以更喜欢把你的注释映射放在getter的字段成员上)

/** 
    * When both entity class and target table SHARE the same name 
    * You do not need @Table annotation 
    */ 
@Entity 
public class SubPart implements Serializable { 

    @EmbeddedId 
    private SubPartId subPartId; 

    @ManyToOne(fetch=FetchType.LAZY) 
    @JoinColumn(name="PART_ID", insertable=false, updateable=false) 
    private Part part; 

    @ManyToOne(fetch=FetchType.LAZY) 
    @JoinColumn(name="SUP_PART_ID", insertable=false, updateable=false) 
    private SubPart subPart; 

    /** 
     * required no-arg constructor 
     */ 
    public SubPart() {} 
    public SubPart(SubPartId subPartId) { 
     this.subPartId = subPartId; 
    } 

    // getter's and setter's 

    /** 
     * It MUST implements Serializable 
     * It MUST overrides equals and hashCode method 
     * It MUST has a no-arg constructor 
     * 
     * Hibernate/JPA 1.0 does not support automatic generation of compound primary key 
     * You SHOULD set up manually 
     */ 
    @Embeddable 
    public static class SubPartId implements Serializable { 

     @Column(name="PART_ID", updateable=false, nullable=false) 
     private Integer partId; 
     @Column(name="SUB_PART_ID", updateable=false, nullable=false) 
     private Integer subPartId; 

     /** 
      * required no-arg constructor 
      */ 
     public SubPartId() {} 
     public SubPartId(Integer partId, Integer subPartId) { 
      this.partId = partId; 
      this.subPartId = subPartId; 
     } 

     // getter's and setter's 

     @Override 
     public boolean equals(Object o) { 
      if(!(o instanceof SubPartId)) 
       return null; 

      final SubPartId other = (SubPartId) o; 
      return new EqualsBuilder().append(getPartId(), other.getPartId()) 
             .append(getSubPartId(), other.getSubPartId()) 
             .isEquals(); 
     } 

     @Override 
     public int hashCode() { 
      return new HashCodeBuilder().append(getPartId()) 
             .append(getSubPartId()) 
             .toHashCode(); 
     } 

    } 

} 

通知部分和子部分的映射已被标记为插入=假,可更新=假由于映射已在该化合物的主键被定义。休眠不允许您将两个属性映射到同一列,除非您标记insertable = false,updateable = false。否则,你将看到这个漂亮的例外

应标有插入=假,可更新=假

+0

+1尼斯的答案。 – 2010-08-29 07:33:55

0

我想我会在课堂上部分声明类型地图<部分的领域,分部>并宣布它作为@OneToMany。

实际上,在这个特殊情况下,它可能是一个Map < Part,Integer >,因为唯一的其他字段是数量。 SubPart类不是必需的。