2014-09-25 13 views
5

Was ist die geeignete Methode zum Erstellen eines untergeordneten Objekts eines persistenten Superobjekts mit Hibernate?So erstellen Sie ein untergeordnetes Objekt eines vorhandenen Superobjekts mithilfe der Vererbung von JOINED und Hibernate

Betrachten Sie folgendes Beispiel: In der Datenbank ist persistent User mit ID 1, firstName Kevin und laseName Smith. Zu der Zeit ist das Datenbankmodell der neuen Entität Auditor erweitert, die eine Kindklasse von User ist. Für die Vererbung wird die Strategie JOINED verwendet, sodass das Datenbankmodell jetzt über Tow-Tabellen verfügt: Benutzer und Auditor. Diese Tabellen sind mit user_id FK verbunden.

Ich möchte von Kevin Smith Objekttyp Auditor erstellen und persistieren. Problem ist, dass Operationen transaktional und Hibernate-Würfe NonUniqueObjectException sind. Gibt es einen Weg, wie ein persistentes Objekt sicher untergeordnet werden kann? Ich habe versucht, gegebenes Benutzerobjekt zu vertreiben, aber immer noch dasselbe.

Benutzer Einheit

@Entity 
@Table(name = "user") 
@Inheritance(strategy = InheritanceType.JOINED) 
public class User{ 

    private Long id; 
    private String firstName; 
    private String lastName; 

    // getters and setters 
} 

Auditor Einheit

@Entity 
@Table(name = "auditor") 
public class Auditor extends User { 
    // some properties 
} 

Logic

public void createAuditorOfUser(final long userId) { 
    final User user = userService.getUserById(userId); 
    // ... 
    final Auditor auditor = new Auditor(); 
    auditor.setId(user.getId()); 
    auditor.setFirstName(user.getFirstName()); 
    auditor.setLastName(user.getLastName()); 
    userService.evict(user); 
    // will throw NonUniqueObjectException 
    auditorService.update(auditor); 
    // ... 
} 

Ich hoffe, das Problem ist klar, wenn nicht, werde ich versuchen, die Beschreibung zu verbessern.

+0

hinzufügen Code tun können als du die Ausnahme bekommen hast. 'NonUniqueObjectException' bedeutet, dass eine einzelne Sitzung mehrere Objekte desselben Typs in der Sitzung mit demselben Bezeichner enthält. – Chaitanya

+0

@ Chaitanya tat ich. –

+0

Versuchen Sie, session.merge() aufzurufen, bevor Sie evict() aufrufen. – Jack

Antwort

1

Ich denke, dass Hibernate absichtlich ein solches Verhalten einschränken. Natürlich können Sie es mit nativer SQL-Problemumgehung (wie Sie bereits getan haben).

In Java können wir auch kein Objekt der Superklasse in eine Unterklasse umwandeln und dann neue Felder desselben Objekts füllen. Erstellen Sie stattdessen eine neue Instanz der Unterklasse und kopieren Sie dann die Felder.

Scheint wie Eins-zu-eins-Beziehung Zuordnung passt für die Funktionalität, die Sie benötigten.

0

Ich denke, das Problem ist, dass Sie einen Benutzer als eine Rolle erstellen möchten, und ein Benutzer ist nicht eine Rolle, ich denke, es passt ein Prüfer zu sagen, ist eine Rolle (Vererbung) und ein Er hat eine Rolle (Komposition), so vielleicht müssen Sie die Benutzer gemeinsame Eigenschaften in einem Unternehmen haben, und die die Rolle Tabelle ist, wo Sie abstrakt benötigen Erbe

so etwas wie diese

@Entity 
@Table(name = "user") 
public class User{ 

    //user properties 

    //Here is where you will share the user 
    @optional = false, cascade = CascadeType.ALL, mappedBy = "user" 
    private Role role 

    // getters and setters 
} 

und hier deine Rolle Einheit mit wird der übergeordneten Klasse

@Entity 
@Inheritance(strategy = InheritanceType.JOINED) 
public abstract class Role implements Serializable { 

    @SequenceGenerator(name = "ROLE_SEQ", sequenceName = "ROLE_SEQ", allocationSize = 1) 
    @GeneratedValue(generator = "ROLE_SEQ") 
    @Id 
    private Long idRole; 
    @OneToOne(optional = false) 
    private User user; 
//getter and setters 

}

und Ihre spezifische Rolle in dieser Art und Weise

@Entity 
@Table(name = "auditor") 
public class Auditor extends Role { 
    // some properties 
} 

So werden Sie so etwas wie dies in Java

User user = new User(); 
//set all the properties that you need for user or the reference for an existing user 
    . 
    . 
    //Set the role that you need 
    Auditor auditor = new Auditor(); 
    auditor.setUser(user); 
    user.setRole(auditor); 

    userDAO.insert(user); 
Verwandte Themen