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

前端 未结 9 615
抹茶落季
抹茶落季 2020-12-30 20:05

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 appl

相关标签:
9条回答
  • 2020-12-30 20:34

    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.

    0 讨论(0)
  • 2020-12-30 20:40

    We had got similar requirement, in which we need to copy entity at certain point of transaction and use it for Audit. Solution is pretty simple. We can use Json Object Mapper.

    public class Employee {
       public int id;
       public String name;
    }
    
    Employee employee = entityManager.find(Employee.class, ID); 
    
    ObjectMapper mapper = new ObjectMapper();
    Employee deepCopiedEmployee = mapper.readValue( mapper.writeValueAsString( employee ), Employee.class );
    deepCopiedEmployee.setId(null);
    

    Another option is to use In-house Spring Utils.

    org.springframework.beans.BeanUtils.copyProperties(<source>, <target>, ...ignoredPropertied)
    
    Employee copiedEmployee = new Employee();
    BeanUtils.copyProperties(employee, copiedEmployee, id)
    

    Note: When using BeanUtils, Bean will be tracked in transaction. i.e. if any changes done is source bean during transaction will be reflected in target copied bean.

    0 讨论(0)
  • 2020-12-30 20:51

    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.

    0 讨论(0)
  • 2020-12-30 20:52

    Have a look at following link. one of the most powerful cloning mechanism which can be utilized in most effective fashion with hibernate

    https://thoughtfulsoftware.blogspot.com/2013/05/using-variable-depth-copy-to-prevent.html

    0 讨论(0)
  • 2020-12-30 20:53

    1- Add commons-lang dependency to pom.xml file

    <dependency>
        <groupId>commons-lang</groupId>
        <artifactId>commons-lang</artifactId>
        <version>2.6</version>
    </dependency>
    

    2- Import org.apache.commons.lang.SerializationUtils

    3- Use SerializationUtils.clone(oldObj)

    ex. Class1 newObj = (Class1) SerializationUtils.clone(oldObj);

    see also java-deep-copy

    0 讨论(0)
  • 2020-12-30 20:53

    Either you can clone if the object is clonable or you can define a method/constructor for the object you want to copy taking a parameter of itself and copying everthing you need, into a new instance and returning it to you.

    0 讨论(0)
提交回复
热议问题