значения объекта копии спящего режима в новый объект с новым сгенерированным идентификатором

Я использую реляционный db, используя один столбец pk с несколькими вложенными таблицами. Мне нужно добавить простое архивирование в мой проект. Архивирование происходит только тогда, когда приложение достигает определенного состояния, поэтому я надеялся сделать копию моего существующего объекта спящего режима в новый экземпляр, где новый экземпляр будет сохранен с новым идентификатором, оставив объект без изменений. Я не могу понять, как скопировать существующий объект в новый экземпляр без необходимости вручную устанавливать каждое новое поле экземпляра. Кто-нибудь знает простой способ сделать это?

Ответ 1

Я также работаю с Hibernate, и у меня есть то же требование, которое у вас есть. Я последовал за тем, чтобы реализовать Cloneable. Ниже приведен пример кода, как это сделать.

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

Или вы можете пойти на решение, основанное на отражении, но я не буду этого рекомендовать. Проверьте этот сайт для получения более подробной информации.

Ответ 2

Просто извлеките объект, отсоедините его, установите id в значение null и сохраните его.

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

Если у вашего объекта есть отношения oneToMany, вам нужно будет повторить операцию для всех детей, но вместо идентификатора родительского объекта (сгенерированного после вызова persist) вместо null.

Конечно, вам придется удалить любой CASCADE persist persist в своих отношениях OneToMany, иначе ваш persist будет создавать дубликаты всех детей в результате сбоев с ограничениями DB или fk.

Ответ 3

Вы можете клонировать объект и уничтожить идентификатор и сохранить его обратно, чтобы назначить новый идентификатор.

так

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

в этом случае createCopyWithNoId() создаст клон объекта и установит для поля Id значение null. когда теперь вы добавляете новый клон, движок hibernate увидит его как новый объект, он сохранит его, и база данных назначит новый первичный ключ.

Обратите внимание, что я избегал вызова метода clone, потому что то, что выходит, не является точным клоном, поскольку мы манипулируем Id (устанавливаем его значение null);

Другой способ - добавить конструктор, который взял объект типа person и создал новый объект, но просто не установил поле Id, оставляя его по умолчанию по умолчанию null. Снова вы продолжаете использовать DAO.

Ответ 5

Либо вы можете клонировать, если объект клонирован, либо вы можете определить метод/конструктор для объекта, который вы хотите скопировать, взяв параметр самого себя и скопировав все, что вам нужно, в новый экземпляр и вернув его вам.