Я использую реляционный 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.
Ответ 4
Посмотрите следующую ссылку. один из самых мощных механизмов клонирования, который может быть использован наиболее эффективным способом с спящим режимом
http://thoughtfulsoftware.blogspot.in/2013/05/using-variable-depth-copy-to-prevent.html
Ответ 5
Либо вы можете клонировать, если объект клонирован, либо вы можете определить метод/конструктор для объекта, который вы хотите скопировать, взяв параметр самого себя и скопировав все, что вам нужно, в новый экземпляр и вернув его вам.