Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to deep copy a Hibernate entity while using a newly generated entity identifier

I'm using a relational DB using a single column pk with a few nested tables.

I need to add a simple archiving to my project. The archiving only happens when the application reaches a particular state, so what I was hoping to do was copy my existing hibernate object into a new instance where the new instance would be saved with a new ID while leaving the existing object intact.

I can't seem to figure out how to copy the existing object into a new instance without manually having to set every single new instance field.

Does anybody know of a simple way of doing this?

like image 438
Code Junkie Avatar asked Mar 30 '12 14:03

Code Junkie


2 Answers

Just retrieve the object, detach it, set the id to null and persist it.

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

If your object have oneToMany relationships, you will have to repeat the operation for all the children but setting your parent object id (generated after the persist call) instead of null.

Of course you will have to remove any CASCADE persist on your OneToMany relationships cause otherwise your persist will create duplicates of all children in DB or fk constraint failures.

like image 127
Gab Avatar answered Oct 05 '22 05:10

Gab


I am also working with Hibernate and I got the same requirement you got. What I followed was to implement Cloneable. Below is a code example of how to do it.

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

Or you could go to a reflection based solution but I won't recommend that. Check this website for more details.

like image 31
Chan Avatar answered Oct 05 '22 06:10

Chan