2010-08-20 7 views
1

J'ai deux tables Part et SubPart. La table Part a des champs généraux comme id, name, desc, etc. La table SubPart a part_id, sub_part_id comme clé composite. Ces deux colonnes font référence à la table Part et ont un mappage un à plusieurs pour chacune d'elles, comme pour chaque ID_part dans la table Part, il peut y avoir plusieurs entrées dans la table SubPart pour les deux colonnes. J'ai un problème pour définir la clé composite pour la table SubPart. J'ai essayé le tag Embedded mais ça ne fonctionne pas. Comment puis-je résoudre ce problème? Merci beaucoup.Clé composite Hibernate qui est la clé avant d'une autre table

Partition de ce type.

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

Sous Partie Tableau

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

Répondre

6

Vous avez dit

J'ai problème définir la clé composite pour la table sous-partie

Lorsque vous avez une clé primaire composée, vous doit définir une classe (généralement une classe interne statique) qui définit votre clé de primé composée (Juste un conseil: parce que Hibernate utilise des proxies, préférez placer votre mapping annoté sur les getters au lieu des membres du champ)

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

    } 

} 

partie de l'Avis et la sous-partie la cartographie a été marquée comme insérable = false, actualisable = false Parce que le mappage a été défini dans la clé primaire composé. Hibernate ne vous permet pas de mapper deux propriétés AVEC LA MÊME COLONNE sauf si vous marquez insertable = false, updateable = false. Sinon, vous verrez cette belle exception

doit être marqué avec la réponse insérable = false, actualisable = false

+0

+1 Nice. –

0

Je pense que je déclarerais un champ de type Carte < Partie, dans la partie sous-partie > de classe et déclarer comme @OneToMany.

En fait, dans ce cas particulier, il pourrait s'agir d'une pièce < Pièce, Integer > parce que le seul autre champ est la quantité. La classe SubPart n'est pas nécessaire.

Questions connexes