2012-03-30 15 views
16

Uso un db relazionale utilizzando una singola colonna pk con alcune tabelle nidificate. Devo aggiungere una semplice archiviazione al mio progetto. L'archiviazione avviene solo quando l'applicazione raggiunge uno stato particolare, quindi quello che speravo di fare era copiare il mio oggetto di ibernazione esistente in una nuova istanza in cui la nuova istanza sarebbe stata salvata con un nuovo ID lasciando intatto l'oggetto esistente. Non riesco a capire come copiare l'oggetto esistente in una nuova istanza senza dover manualmente impostare ogni singolo nuovo campo dell'istanza. Qualcuno sa di un modo semplice per farlo?ibernare i valori degli oggetti di copia nel nuovo oggetto con il nuovo ID generato

risposta

6

Sto anche lavorando con Hibernate e ho ottenuto lo stesso requisito che hai ottenuto. Quello che ho seguito è stato quello di implementare Cloneable. Di seguito è riportato un esempio di codice su come farlo.

class Person implements Cloneable { 

     private String firstName; 
     private String lastName; 

     public Object clone() { 

      Person obj = new Person(); 
      obj.setFirstName(this.firstName); 
      obj.setLastName(this.lastName); 

      return obj; 
     } 

     public String getFirstName() { 
      return firstName; 
     } 

     public void setFirstName(String firstName) { 
      this.firstName = firstName; 
     } 

     public String getLastName() { 
      return lastName; 
     } 

     public void setLastName(String lastName) { 
      this.lastName = lastName; 
     } 
    } 

Oppure potresti andare a una soluzione basata su riflessione ma non lo consiglio. Controlla questo website per maggiori dettagli.

+1

Come gestisci le tabelle nidificate come oneToMany's etc? Avevo paura di dover impostare nuovamente tutte le variabili oggetto.:( –

+1

Il mio caso non riguardava oggetti nidificati quindi non ho affrontato il problema ... temo che dovrai copiare in profondità ... C'è sempre una generazione che può essere fatta ... – Chan

+0

Puoi indicarmi a un articolo sulla generazione? –

2

È possibile clonare l'oggetto e cancellare l'ID e salvarlo nuovamente in modo da assegnare un nuovo ID.

così

Person person = EmployeeDAO.get(empId); 
Person newPersonCopy = person.createCopyWithNoId() 
EmployeeDAO.add(newPersonCopy); 

in questo caso il createCopyWithNoId() creerebbe un clone dell'oggetto e impostare il campo Id null. quando ora aggiungi il nuovo clone, il motore di ibernazione lo vedrà come un nuovo oggetto lo manterrà e il database assegnerà una nuova chiave primaria.

Si noti che ho evitato di chiamare il metodo clone perché ciò che viene fuori non è un clone esatto mentre manipoliamo l'Id (impostandolo su null);

Un altro modo per andare sarebbe quello di aggiungere un costruttore che ha preso un oggetto di tipo persona e ha creato un nuovo oggetto ma semplicemente non ha impostato il campo ID lasciandolo al suo valore predefinito di null. Anche in questo caso si continua a utilizzare il DAO.

+1

Potrebbe elaborare un po 'di più su questo. Non sono completamente sicuro di cosa sia CreateCopyWithNoId. Penso che sia qui che ho bisogno di chiarimenti. Inoltre, questo potrebbe eseguire un clone profondo? –

0

O è possibile clonare se l'oggetto è clonabile oppure è possibile definire un metodo/costruttore per l'oggetto che si desidera copiare prendendo un parametro di se stesso e copiando tutto ciò che è necessario, in una nuova istanza e restituendolo all'utente.

23

Basta recuperare l'oggetto, staccarlo, impostare l'id su null e mantenerlo.

MyEntity clone = entityManager.find(MyEntity.class, ID); 
entityManager.detach(clone); 
clone.setId(null); 
entityManager.persist(clone); 

Se l'oggetto hanno rapporti OneToMany, si dovrà ripetere l'operazione per tutti i bambini, ma impostando l'oggetto id genitore (generato dopo la chiamata persist) invece di null.

Ovviamente sarà necessario rimuovere qualsiasi CASCADE persist sulle tue relazioni OneToMany, altrimenti il ​​tuo persistente creerà i duplicati di tutti i bambini negli errori di DB o fk constraint.

+0

funziona come previsto –

+0

mi aspettavo che questo approccio funzionasse ma .... sorpresa, sorpresa I un'eccezione org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke() quando provo a reimpostare l'id – Legna

+1

su un bambino? Lo hai staccato bef minerale? (il distacco non è ricorsivo a meno che con cascadeType = DETACH) – Gab

Problemi correlati