2010-02-20 12 views
8

Ist es notwendig, dass Composite-ID Klasse zugeordnet werden sollte ??Hibernate Composite Key

kann es so sein?

<composite-id> 
    <key-property=..../> 
    <key-property=..../> 
</composite-id> 

oder sollte es sein

<composite-id class=....> 
    <key-property=..../> 
    <key-property=..../> 
</composite-id> 

sollte das notwendig, wenn wir zusammengesetzten Schlüssel haben, dann sollten diese Klasse equals() und override() Methode implementieren?

Antwort

26

Hibernate muss Kennungen vergleichen und serialisieren können. Daher muss die Bezeichnerklasse serialisierbar sein und hashCode() und equals() in Übereinstimmung mit dem Begriff der zusammengesetzten Schlüsselgleichheit der Datenbank überschreiben.

Wenn Sie eine zusammengesetzte ID als Eigenschaften der Entität zugeordnet haben, ist die Entität selbst der Bezeichner.

Ein zweiter Ansatz eine zugeordnetes Verbund Kennung genannt wird, in dem die Kennung benannten Eigenschaften innerhalb des < Composite-id > Elements sowohl auf die persistenten Klasse dupliziert werden und eine separate Kennung Klasse

Schließlich ist eine Verbund-ID kann eine Komponentenklasse sein. In diesem Fall ist die Komponentenklasse die Bezeichnerklasse.

Beachten Sie, dass es dringend empfohlen wird, die ID eine separate Klasse zu haben. Andernfalls haben Sie nur sehr ungünstige Möglichkeiten, Ihr Objekt mit session.get() oder session.load() zu suchen.

Relevante Abschnitte der Referenzdokumentation:

In diesem Beispiel wird eine Verbund-ID als Eigenschaften des Unternehmens abgebildet. (Angenommen, Sie definieren die Klasse Employee).

<composite-id> 
    <key-property name="EmployeeNumber"/> 
    <key-property name="Dependent"/> 
</composite-id> 

class EmployeeAssignment implements Serializable 
{ 
    string getEmployeeNumber() 
    void setEmployeeNumber(string value) 
    string getDepartment() 
    void setDepartment(string value) 
    boolean equals(Object obj) 
    int hashCode() 
} 

A kartiert Kompositpartikel-ID:

<composite-id class="EmployeeAssignmentId" mapped="true"> 
    <key-property name="EmployeeNumber"/> 
    <key-property name="Dependent"/> 
</composite-id> 

class EmployeeAssignment 
{ 
    string getEmployeeNumber() 
    void setEmployeeNumber(string value) 
    string getDepartment() 
    void setDepartment(string value) 
} 

class EmployeeAssignmentId implements Serializable 
{ 
    string getEmployeeNumber() 
    void setEmployeeNumber(string value) 
    string getDepartment() 
    void setDepartment(string value) 
    boolean equals(Object obj) 
    int hashCode() 
} 

eine Komponente als Verbund-ID:

<composite-id name="Id" class="EmployeeAssignmentId"> 
    <key-property name="EmployeeNumber"/> 
    <key-property name="Dependent"/> 
</composite-id> 

class EmployeeAssignment 
{ 
    EmployeeAssignmentId getId() 
    void setId(EmployeeAssignmentId value) 
} 

class EmployeeAssignmentId implements Serializable 
{ 
    string getEmployeeNumber() 
    void setEmployeeNumber(string value) 
    string getDepartment() 
    void setDepartment(string value) 
    boolean equals(Object obj) 
    int hashCode() 
} 
+0

Beispiel verwirrend. auch, was ist abhängig von der Composite-ID? Meinst du, Abteilung? so oder so, immer noch ein verwirrendes Beispiel. könnte durch Kommentare geklärt werden, um es zu erklären. – KyleM

+0

Wenn Sie die Entität selbst als Bezeichner angeben lassen, bedeutet das, dass der equals und der hashcode nur die zusammengesetzten IDs und keine anderen Felder verwenden können, um auf Gleichheit zu prüfen? – CowZow

4

beides ist möglich. Wenn Sie

verwenden
<composite-id> 
    <key-property=..../> 
    <key-property=..../> 
</composite-id> 

Dann ist keine separate Klasse erforderlich, um den Schlüssel darzustellen. Die ID-Werte werden den Eigenschaften der Entität selbst entnommen.

Wenn Sie

<composite-id class="...."> 
    <key-property=..../> 
    <key-property=..../> 
</composite-id> 

Dann wird die angegebene Klasse wird ein als Halterung für die wichtigsten Eigenschaften verwendet werden. Die Entitätsklasse muss jedoch auch diese Eigenschaften aufweisen - die Werte werden sowohl in der Entitätsklasse als auch in der ID-Verbundklasse gespeichert. Die Entitätsklasse kennt die Schlüsselklasse nicht. Nicht sehr nett, meiner Meinung nach.

Es ist ein schöner dritte Ansatz, in der Dokumentation beschrieben here:

<composite-id name="id" class="OrderLineId"> 
    <key-property name="lineId"/> 
    <key-property name="orderId"/> 
    <key-property name="customerId"/> 
</composite-id> 

Hier wird der Verbundschlüssel durch die Klasse repräsentiert wird OrderLineId, eine Instanz von der unter dem Feld id in der Entity-Klasse gespeichert . Dies hält die Trennung zwischen Entity und Key sauberer.

+0

"Wenn Sie" ... verwenden, wollten Sie Code nach dieser Zeile einfügen? –

+0

@skaffman, ich bin auch auf der Suche nach Code für obige Logik – Vish

+0

404 auf Ihrem Doc-Link. – orbfish

2

Wenn Sie einen zusammengesetzten Schlüssel haben, die Beziehungen zu anderen Entitäten enthält, mag es dies:

<composite-id> 
    <key-many-to-one name="employee" column="FK_EMPLOYEE" entity-name="net.package.name.Employee" /> 
    <key-many-to-one name="department" column="FK_DEPARTMENT" entity-name="net.package.name.Department" /> 
</composite-id> 
+0

Leider funktioniert nicht, Mapping-Ausnahme wird ausgelöst: _Repeated Spalte in Zuordnung für Entität_. – mnn

Verwandte Themen