2011-09-22 10 views
15

Ho una domanda riguardante JPA 2.0, Hibernate e "orphanRemoval".JPA 2.0/Hibernate e "orphanRemoval": la semplice sostituzione di un'entità non rimuove quella precedente

Prima la mia configurazione:

  • Primavera 3.0.5.RELEASE
  • SprnigData JPA 1.0.1.RELEASE
  • Hibernate 3.5.2-finali
  • DBMS: PostgreSQL 9.0

Ho due classi di entità piuttosto semplici, "Utente" e "AvatarImage", un "Utente" ha un "AvatarImage", e quindi tra "Utente" e "AvatarImage" c'è il parente ionship.

Nella categoria "User", la proprietà si presenta in questo modo:

// class "User" 
@OneToOne(cascade = CascadeType.ALL, fetch=FetchType.LAZY, orphanRemoval = true) 
private AvatarImage avatarImage; 

Quindi questo significa che, se la proprietà "avatarImage" viene impostato su null, il riferimento tra "utente" e "AvatarImage" è rimosso e il meccanismo "orphanRemoval" cancellerà "avatarImage" dal database (correggimi se ho torto).

Così quando aggiorno il "avatarImage" per un determinato utente, ho attualmente a scrivere questo:

user.setAvatarImage(null); // First set it to null 
userRepository.save(user); // Now "orphanRemoval" will delete the old one 

user.setAvatarImage(theNewAvatarImage); 
userRepository.save(user); 

Quindi impostando la proprietà "avatarImage" prima di nulla, salvare il "utente", e poi imposta la nuova AvatarImmagine "theNewAvatarImage", salvando nuovamente l'utente.

Questo è l'unico modo in cui attualmente funziona per me: "orphanRemoval" cancellerà il vecchio "avatarImage" impostandolo su "null" e quindi salvando l'utente.

Ma, avrei pensato che questo codice dovrebbe funzionare anche:

user.setAvatarImage(theNewAvatarImage); 
userRepository.save(user); 

Così Tralascio l'impostazione del "avatarImage" a "null", ma solo impostando "theNewAvatarImage", che sostituisce il vecchio "avatarImage". Ma questo non funziona, la vecchia AvatarImage non viene rimossa dal database al momento del commit della transazione.

Qualcuno sa, perché il secondo codice (sostituendo semplicemente AvatarImage senza impostarlo su "null" prima) non funziona?

Apprezzo molto tutto l'aiuto che si può offrire

Grazie mille!

risposta

12

Questo è correlato ai biglietti Hibernate JIRA HHH-5559 e HHH-6484. Generalmente, Hibernate, a partire da oggi, richiede di impostare il riferimento su null e svuotare il contesto di persistenza, prima di fornire un nuovo valore alla relazione (vedere il test case in HHH-6484); è solo in questo caso che Hibernate emette un'istruzione SQL DELETE, fornendo un'implementazione interrotta (IMHO) per orphanRemoval.

In breve, è necessario attendere che i bug vengano corretti, o scrivere codice per annullare i riferimenti e svuotare il contesto di persistenza, o utilizzare un provider JPA che supporti orphanRemoval in questo modo (EclipseLink 2.3.0 fa) .

1

Dalla relazione @OneToMany, questo è correlato al ticket Hibernate JIRA HHH-6709. Si prega di votare per questi in modo da ottenere un po 'di attenzione.

Problemi correlati