2009-05-27 4 views
3

Angesichts der folgenden:Hibernate/JPA Parent-Child - ist es in Ordnung für Parent equals()/hashCode() die DB Id zu verwenden?

@Entity 
public class Parent implements Serializable { 
    @Id 
    private Long id; 
    // mapped ManyToOne below... 
    private List<Child> children = new ArrayList<Child>(); 

    ... 

} 

Ist es eine schlechte Praxis Parent.equals() und Parent.hashCode() id nur zu haben, verwenden? Ich verstehe, dass Child.equals() und Child.hashCode() einen unveränderlichen Satz von Attributen für einen "natürlichen Schlüssel" verwenden sollten, damit sie von Parent korrekt verwaltet werden. Wenn Parent jedoch immer ein Objekt der obersten Ebene ist (dh es ist niemals die inverse Seite einer Assoziation), ist irgendetwas falsch daran, nur die ID zu verwenden?

Gibt es unerwünschte Effekte, die sich dadurch bemerkbar machen können? Ich vermute, dass, wenn ich das tue, wenn ich ein Kind hinzufüge (oder entferne), Hibernate wird nicht in der Lage zu sagen, dass Eltern geändert hat (und muss in DB aktualisiert werden)? Sollte in diesem Fall die Eigenschaft children für Parent.equals() und Parent.hashCode() verwendet werden?

ich frage, weil die Hibernate docs explicity sage nicht die @Id Eigenschaft für einen „natürlichen Schlüssel“ zu verwenden ...

Antwort

5

Das primäre Problem mit der ID als equals und hashCode Basis verwendet, sind unpersisted Objekte. Diese Objekte beginnen vermutlich alle mit der gleichen ID und dies kann nicht korrekt mit Gleichheit verglichen werden. Selbst wenn Sie die Objekte nie in eine Sammlung stellen, wenn sie über eine API verfügbar gemacht werden und jemand anderes eine Instanz von ihnen erstellen und sie in eine Sammlung einfügen kann, haben Sie sich selbst für einige böse Fehler geöffnet.

+0

Ich verstehe, was Sie sagen, aber technisch, wenn ID ist Null, dann sind sie wirklich gleich: sie sind beide nicht übergeordnet Elternobjekte. Für mein Beispiel oben mit nur diesen beiden Eigenschaften (ID und Kinder), wie würden Sie vorschlagen, equals() und hashCode() zu implementieren? Müsste ich mehr Eigenschaften einführen? – GreenieMeanie

+0

Auch wenn es keinen Hibernate gibt, können Sie Mutatoren für Felder zulassen, die für equals() und hashCode() verwendet werden? Jemand könnte eine Instanz in ein HashSet setzen, ein Feld ändern, das den Hash-Code beeinflusst, und auf diese Weise das Set aufbrechen. Aber es zu verbieten scheint ein bisschen hart zu sein. Ich neige dazu, dass Sie jeden Fall einzeln betrachten und die Vor- und Nachteile gegeneinander abwägen müssen ... – waxwing

+1

@Greenie: Wenn ich Daten von einer anderen Quelle importiere, könnte ich einen ganzen Graph neuer Objekte erstellen, die ich habe irgendwo speichern, bevor sie persistieren und den Ruhezustand spülen. Nur weil sie die ID 0 haben, heißt das nicht, dass sie gleich sind. Das heißt, sie haben noch keine ID, aber das ist alles. – Jherico

Verwandte Themen