DarthShader
Erfahrenes Mitglied
Hallo,
ich habe ein Hiberante-Mapping-Problem mit dem folgenden Szenario. Ich bin nicht sicher, wie ich das mapping konfigurieren muss.
Dies ist die Klasse "Customer" als "Haupttabelle", sie hat keinerlei Foreign-Keys:
Die folgende Klasse beschreibt eine zweite Tabelle:
(Dies ist eine sehr vereinfachte Version meines DB-Schemas/des Domain Modols, aber es gibt das Problem gut wieder.)
Man kann sehen, dass ein Customer zwei Locations hat (Home und Work). Der folgende Code zeigt, wie man ein Customer Objekt erstellt, welches persistiert werden kann:
Nun habe ich ein Customer Objekt, welches ich problemlos mit Hibernate in die Datenbank schreiben kann. Jedoch bin ich nicht in der Lage, dieses Objekt wieder aus der Datenbank zu laden. Versuche ich das, erscheint folgende Exception:
Die Erklärung ist (so denke ich), dass man nun zwei Objekte (Datensätze) in der Tabelle für die Locations hat, die beide zum selben Customer gehören (über den Foreign Key). Wenn Hibernate nun ein Join macht, so findet es zwei Location Objekte vor - jedoch wurde nur eines erwartet.
Was ich nun möchte ist, dass ich das Property "homeLocation" der Klasse "Customer" auf den entsprechenden Datensatz mappe, der in der Spalte "locationType" den Wert "HOME" hat. Entsprechend soll "workLocation" so aufgelöst werden, dass er den Datensatz nimmt, der in der Spalte "locationType" den Wert "WORK" hat.
Wie muss das (annotation basierte) Mapping nun aussehen? Wie kann ich Hibernate anweisen, die Spalte "locationType" (zusätzlich zur "customer_id" Spalte) für die Identifikation des korrekten Datensatzes zu verwenden?
Über Eure Hilfe würde ich mich sehr freuen
Vielen Dank!
ich habe ein Hiberante-Mapping-Problem mit dem folgenden Szenario. Ich bin nicht sicher, wie ich das mapping konfigurieren muss.
Dies ist die Klasse "Customer" als "Haupttabelle", sie hat keinerlei Foreign-Keys:
Java:
@Entity
@Table( name = "customer" )
public class Customer
{
@Id
@GeneratedValue( strategy = GenerationType.IDENTITY )
private Integer id;
@OneToOne( mappedBy = "customer", cascade = CascadeType.ALL )
private Location homeLocation;
@OneToOne( mappedBy = "customer", cascade = CascadeType.ALL )
private Location workLocation;
// Getters and setters
// ....
}
Die folgende Klasse beschreibt eine zweite Tabelle:
Java:
@Entity
@Table( name = "location" )
public class Location
{
public enum LocationType {
HOME, WORK
}
@Id
@GeneratedValue( strategy = GenerationType.IDENTITY )
private Integer id;
@ManyToOne( optional = true )
@JoinColumn( name = "customer_id" )
private Customer customer;
private LocationType locationType;
prviate String someOtherData;
// Getters and setters
// ....
}
(Dies ist eine sehr vereinfachte Version meines DB-Schemas/des Domain Modols, aber es gibt das Problem gut wieder.)
Man kann sehen, dass ein Customer zwei Locations hat (Home und Work). Der folgende Code zeigt, wie man ein Customer Objekt erstellt, welches persistiert werden kann:
Java:
Location homeLocation = new Location();
homeLocation.setLocationType( LocationType.HOME );
Location workLocation = new Location();
workLocation.setLocationType( LocationType.WORK );
Customer customer = new Customer();
customer.setHomeLocation( homeLocation );
customer.setWorkLocation( workLocation );
homeLocation.setCustomer( customer );
workLocation.setCustomer( customer );
Nun habe ich ein Customer Objekt, welches ich problemlos mit Hibernate in die Datenbank schreiben kann. Jedoch bin ich nicht in der Lage, dieses Objekt wieder aus der Datenbank zu laden. Versuche ich das, erscheint folgende Exception:
Java:
org.hibernate.HibernateException: More than one row with the given identifier was found:
9, for class: de.foo.domain.Customer
Die Erklärung ist (so denke ich), dass man nun zwei Objekte (Datensätze) in der Tabelle für die Locations hat, die beide zum selben Customer gehören (über den Foreign Key). Wenn Hibernate nun ein Join macht, so findet es zwei Location Objekte vor - jedoch wurde nur eines erwartet.
Was ich nun möchte ist, dass ich das Property "homeLocation" der Klasse "Customer" auf den entsprechenden Datensatz mappe, der in der Spalte "locationType" den Wert "HOME" hat. Entsprechend soll "workLocation" so aufgelöst werden, dass er den Datensatz nimmt, der in der Spalte "locationType" den Wert "WORK" hat.
Wie muss das (annotation basierte) Mapping nun aussehen? Wie kann ich Hibernate anweisen, die Spalte "locationType" (zusätzlich zur "customer_id" Spalte) für die Identifikation des korrekten Datensatzes zu verwenden?
Über Eure Hilfe würde ich mich sehr freuen
Vielen Dank!