2014-09-25 7 views
5

qual è il modo appropriato come creare oggetto figlio di oggetto super persistente con Hibernate?Come creare un oggetto figlio di un superoggetto esistente, utilizzando la strategia di ereditarietà JOINED e Hibernate

Considerare l'esempio seguente: Nel database è persistente User con ID 1, firstName Kevin e laseName Smith. Al momento è stato esteso il modello di database della nuova entità Auditor, che è la classe figlio di User. Per l'ereditarietà viene utilizzata la strategia JOINED, quindi il modello di database ora dispone di tabelle di rimorchio: utente e auditor. Queste tabelle sono collegate usando user_id FK.

Vorrei creare un oggetto di tipo revisore di Kevin Smith e persistere. Il problema è che le operazioni sono transazionali e Hibernate genera NonUniqueObjectException. Esiste in qualsiasi modo come castare in modo sicuro l'oggetto persistente fare oggetto figlio? Ho provato a sfrattare dato oggetto utente, ma sempre lo stesso.

entità User

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

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

    // getters and setters 
} 

entità Sindaco

@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); 
    // ... 
} 

Spero che il problema sia chiaro, altrimenti cercherò di migliorare la descrizione.

+0

Aggiungere codice quando hai ottenuto l'eccezione. 'NonUniqueObjectException' significa che una singola sessione ha più oggetti dello stesso tipo in sessione con lo stesso identificatore. – Chaitanya

+0

@Chaitanya l'ho fatto. –

+0

Prova a chiamare session.merge() prima di chiamare evict(). – Jack

risposta

1

Penso che Hibernate limiti intenzionalmente tale comportamento. Ovviamente puoi farlo con la soluzione alternativa nativa di SQL (come hai già fatto).

In Java, inoltre, non è possibile trasmettere un oggetto di super classe a una sottoclasse, quindi riempire nuovi campi dello stesso oggetto. Invece, crea una nuova istanza di sottoclasse quindi copia i campi.

Sembra che la mappatura delle relazioni one-to-one si adatti meglio alla funzionalità richiesta.

0

Credo che il problema è che si desidera creare un utente come un ruolo, e un utente non è un ruolo, credo che si adatta di più a dire un revisore è un ruolo (eredità) e un l'utente ha un ruolo (composizione), quindi forse è necessario avere le proprietà comuni degli utenti in una sola entità e la tabella il ruolo è dove è necessario astratto vostra eredità

Qualcosa di simile

@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 
} 

e ecco il tuo ruolo entità con sarà la classe padre

@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 

}

e il vostro ruolo specifico

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

Quindi, in questo modo si può fare qualcosa di simile 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); 
Problemi correlati