Java Hibernate复合键,它是另一个表的foreigen键

Java Hibernate复合键,它是另一个表的foreigen键,java,hibernate,composite-key,Java,Hibernate,Composite Key,我有两个表部分和子部分。零件表具有id、名称、描述等常规字段。子部分表具有零件id、子零件id作为复合键。这两列都引用零件表,并且每个列都有一对多映射,就像零件表中的每个零件id一样,两列的子部分表中都可以有多个条目。我在定义子部分表的复合键时遇到问题。我尝试了嵌入的标签,但它不起作用。我如何解决这个问题。非常感谢 像这样的零件表 @Entity @Table(name="Part") public class Part { @Id @GeneratedValue @C

我有两个表部分和子部分。零件表具有id、名称、描述等常规字段。子部分表具有零件id、子零件id作为复合键。这两列都引用零件表,并且每个列都有一对多映射,就像零件表中的每个零件id一样,两列的子部分表中都可以有多个条目。我在定义子部分表的复合键时遇到问题。我尝试了嵌入的标签,但它不起作用。我如何解决这个问题。非常感谢

像这样的零件表

@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;
}

我想我应该在类部分声明一个Map类型的字段,并将其声明为@OneToMany


实际上,在这种特殊情况下,它可能是一个映射,因为唯一的其他字段是数量。子部分类是不需要的。

我想我应该在类部分声明一个类型为Map的字段,并将其声明为@OneToMany

实际上,在这种特殊情况下,它可能是一个映射,因为唯一的其他字段是数量。不需要子部分类。

您说过

我在定义子部分表的复合键时遇到问题

当您有一个复合主键时,必须定义一个类(通常是一个静态的内部类),该类定义您的复合主键(只是一个建议:因为Hibernate使用代理,所以更喜欢将带注释的映射放在getter上,而不是字段成员)

请注意,零件和子部分映射已标记为insertable=false,updateable=false,因为映射已在复合主键中定义。Hibernate不允许使用同一列映射两个属性,除非将insertable=false、updateable=false标记为可插入。否则,您将看到这个很好的异常

应标记为insertable=false,updateable=false

你说

我在定义子部分表的复合键时遇到问题

当您有一个复合主键时,必须定义一个类(通常是一个静态的内部类),该类定义您的复合主键(只是一个建议:因为Hibernate使用代理,所以更喜欢将带注释的映射放在getter上,而不是字段成员)

请注意,零件和子部分映射已标记为insertable=false,updateable=false,因为映射已在复合主键中定义。Hibernate不允许使用同一列映射两个属性,除非将insertable=false、updateable=false标记为可插入。否则,您将看到这个很好的异常

应标记为insertable=false,updateable=false

/**
  * 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();  
        }

    }

}