Составной ключ Hibernate, который является ключевым ключом для другой таблицы - PullRequest
1 голос
/ 20 августа 2010

У меня есть две таблицы Part и SubPart. Таблица деталей имеет общие поля, такие как id, name, desc и т. Д. Таблица SubPart имеет part_id, sub_part_id в качестве составного ключа. Оба эти столбца ссылаются на таблицу деталей и имеют сопоставление один ко многим для каждого из них, как для каждого part_id в таблице деталей может быть несколько записей в таблице SubPart для обоих столбцов. У меня проблемы с определением составного ключа для таблицы SubPart. Я попробовал встроенный тег, но он не работает. Как я могу решить эту проблему. Большое спасибо.

Таблица деталей вот так.

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

Таблица Sub Part

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

Ответы [ 2 ]

6 голосов
/ 20 августа 2010

Вы сказали

У меня проблема при определении составного ключа для таблицы SubPart

Если у вас есть составной первичный ключ,вы должны определить класс (обычно статический внутренний класс), который определяет ваш составной первичный ключ (просто совет: поскольку Hibernate использует прокси-серверы, предпочитайте размещать аннотированное отображение на получателе вместо членов поля)

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

    }

}

Примечание Отображение детали и подчасти было помечено как вставляемый = ложь, обновляемый = ложь Поскольку сопоставление было определено в составном первичном ключе.Hibernate не позволяет отображать два свойства с ОДНОЙ ТАКОЙ КОЛОНКОЙ , если только вы не отметите вставку = ложь, возможность обновления = ложь.В противном случае вы увидите это приятное исключение

Должно быть помечено вставляемым = false, обновляемым = false

0 голосов
/ 20 августа 2010

Я думаю, я бы объявил поле типа Mapв классе Part и объявить его как @ OneToMany.

На самом деле, в данном конкретном случае это может быть картапотому что единственное другое поле - это количество.Класс SubPart не нужен.

...