2017-10-05 5 views
1

Si j'ai une clé composée dans une entité Jpa (MyEntity), dois-je ajouter equals() et hashCode() dans l'IdClass (ID dans ce cas)? Il est considéré comme une duplication? ou dans MyEntity "equals et hashCode()", je dois appeler ceux de la classe ID [return new MyEntity.ID (id1, id2) .hashCode(); dans le hashCode() de MyEntity]?Ai-je besoin de redéfinir equals() et hashCode() dans l'IDClass (clé composée) d'un jpa Entité

@Entity 
@IdClass(MyEntity.ID.class) 
public class MyEntity implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    private long id1; 
    @Id 
    private long id2; 

    private String otherField; 
    public static class ID implements Serializable { 
     private static final long serialVersionUID = 1L; 
     private long id1; 
     private long id2; 
     public ID() { 
      super(); 
     } 
     public ID(long id1, long id2) { 
      super(); 
      this.id1 = id1; 
      this.id2 = id2; 
     } 
     public long getId1() { 
      return id1; 
     } 
     public void setId1(long id1) { 
      this.id1 = id1; 
     } 
     public long getId2() { 
      return id2; 
     } 
     public void setId2(long id2) { 
      this.id2 = id2; 
     } 
     @Override 
     public int hashCode() { 
      final int prime = 31; 
      int result = 1; 
      result = prime * result + (int) (id1^(id1 >>> 32)); 
      result = prime * result + (int) (id2^(id2 >>> 32)); 
      return result; 
     } 
     @Override 
     public boolean equals(Object obj) { 
      if (this == obj) { 
       return true; 
      } 
      if (obj == null) { 
       return false; 
      } 
      if (getClass() != obj.getClass()) { 
       return false; 
      } 
      ID other = (ID) obj; 
      if (id1 != other.id1) { 
       return false; 
      } 
      if (id2 != other.id2) { 
       return false; 
      } 
      return true; 
     } 
    } 
    public MyEntity() { 
     super(); 
    } 
    public long getId1() { 
     return id1; 
    } 
    public void setId1(long id1) { 
     this.id1 = id1; 
    } 
    public long getId2() { 
     return id2; 
    } 
    public void setId2(long id2) { 
     this.id2 = id2; 
    } 
    public String getOtherField() { 
     return otherField; 
    } 
    public void setOtherField(String otherField) { 
     this.otherField = otherField; 
    } 
    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result + (int) (id1^(id1 >>> 32)); 
     result = prime * result + (int) (id2^(id2 >>> 32)); 
     result = prime * result + ((otherField == null) ? 0 : otherField.hashCode()); 
     return result; 
    } 
    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) { 
      return true; 
     } 
     if (obj == null) { 
      return false; 
     } 
     if (getClass() != obj.getClass()) { 
      return false; 
     } 
     MyEntity other = (MyEntity) obj; 
     if (id1 != other.id1) { 
      return false; 
     } 
     if (id2 != other.id2) { 
      return false; 
     } 
     if (otherField == null) { 
      if (other.otherField != null) { 
       return false; 
      } 
     } else if (!otherField.equals(other.otherField)) { 
      return false; 
     } 
     return true; 
    } 
} 
+0

je dirais dans les deux classes – XtremeBaumer

Répondre

2

1.

dois-je ajouter equals() et hashCode() dans le IdClass (ID dans ce cas)?

Oui, vous en avez besoin. Voici the documentation:

Une classe de clé primaire composite présente les caractéristiques suivantes:

...

  • Il définit égaux et méthodes hashCode. La sémantique de l'égalité des valeurs pour ces méthodes doit être cohérente avec l'égalité de la base de données pour les types de base de données auxquels la clé est mappée.

...

2.

ou dans le MyEntity "égal à égal et hashCode()", je dois appeler ceux d'ID de classe [retour nouvelle MyEntity.ID (ID1, ID2) .hashCode(); dans le hashCode() de MyEntity]?

Je ne sais pas exactement ce que vous voulez dire, mais vous n'avez pas besoin de construire de nouvelles instances de classe d'ID. Suivez simplement les règles de contrat & hasCode de the documentation. (L'égalisation automatique et hasCode dans votre IDE fonctionnerait aussi bien).

2

S'il vous plaît jeter un oeil à cette question JPA/Hibernate “Composite-id class does not override equals()”

Voici quelques articles de la documentation concernant equals() and hashCode()

Nous recommandons la mise en œuvre equals() et hashCode() à l'aide l'égalité clé affaires . Affaires égalité clé signifie que la méthode equals() compare uniquement les propriétés qui forment la clé de l'entreprise, une clé qui identifierait notre instance dans le monde réel (une naturelle clé candidate )

La question d'égal à égal/hashCode n'est pas trivial, et il n'existe pas non plus de solution unique.

Bien que l'utilisation d'un ID naturel est le mieux pour égaux et hashCode, parfois vous avez seulement l'identifiant de l'entité qui fournit une contrainte unique.

Il est possible d'utiliser l'identifiant de l'entité pour le contrôle de l'égalité, mais il a besoin d'une solution de contournement:

vous devez fournir une valeur constante pour hashCode de telle sorte que la valeur du code de hachage ne change pas avant et après l'entité est rincé.

vous devez comparer l'égalité d'identificateur d'entité uniquement pour entités non transitoires.

également un bon article EqualsandHashCode