Лучший способ обновить некоторые поля отдельного объекта в Hibernate?
Мне было интересно, что лучший способ обновить некоторые поля объекта, который был удален, используя HB на Java. Специально, когда объект имеет атрибуты дочерних объектов. Пример (аннотации удалены и количество полей уменьшено для уменьшения шума):
public class Parent {
int id;
String field2;
...
Child child;
}
public class Child {
int id;
String field3;
}
При обновлении родителя в webapp MVC я могу вызвать родительский экземпляр, используя Session.get(Parent.class, 123), использовать его для заполнения формы и отображения ее. Нет DTO, только дочерний родитель передается в представление и привязан к форме. Теперь я хочу разрешить пользователю обновлять атрибут field2 родителя. Поэтому, когда пользователь отправляет форму, я получаю экземпляр родителя с заполненным id и field2 (я думаю, что структура mvc не имеет значения здесь, все ведет себя в основном одинаково при привязке).
Теперь, какая стратегия лучше всего выполнять обновление объекта? Я могу представить несколько альтернатив, но хочу услышать экспертов:) (Помните, что я не хочу потерять связь между родительским и дочерним экземплярами)
A) Верните родительский экземпляр из сеанса снова и замените вручную обновленные поля
Parent pojoParent; //binded with the data of the Form.
Parent entity = Session.get(Parent.class,pojoParent.getId());
entity.setField2(pojoParent.getField2()).
Я использую это много. Но pojoParent, по-видимому, используется как тайный DTO. Также становится ужасно, если количество полей для обновления становится больше.
B) Храните ребенка где-нибудь (httpSession?) и привяжите его последним.
Parent parent = Session.get(Parent.class,123);
//bind the retrieved parent to the form
// store the Child from parent.getChild() on the httpSession
...
//when the users submits the form...
pojoParent.setChild(someHttpSessionContext.getAttribute('Child'))
Session.save(pojoParent);
Я думаю, что это дерьмо, но я видел это в некоторых проектах...
C) Установите связь между родителем и ребенком как inmutable. Используя updatable = false в отношении, я могу обновить любое родительское поле, не беспокоясь о потере ребенка. В любом случае, это довольно ограничительно, и отношения никогда не будут обновлены.
Итак, как вы думаете, лучший способ решить эту ситуацию?
Заранее благодарю вас!
Ответы
Ответ 1
После загрузки родительского объекта вы сказали
Теперь я хочу разрешить пользователю обновлять атрибут field2 родительского
В зависимости от случая использования вы можете использовать объект UpdateableParent
public class UpdateableParent {
private String field2;
// getter and setter's
}
Теперь наш родительский репозиторий
@Repository
public class ParentRepositoryImpl implements ParentRepository {
@Autowired
private SessionFactory sessionFactory;
public void updateSpecificUseCase(UpdateableParent updateableParentObject) {
Parent parent = sessionFactory.getCurrentSession().load(Parent.class, updateableParentObject.getId());
try {
// jakarta commons takes care of copying Updateable Parent object to Parent object
BeanUtils.copyProperties(parent, updateableParentObject);
} catch (Exception e) {
throw new IllegalStateException("Error occured when updating a Parent object", e);
}
}
}
Его преимущества
- Это безопасно: вы просто обновляете то, что действительно хотите.
- Вам не нужно беспокоиться о структуре MVC (некоторая среда MVC позволяет настроить свойство allowedFields). Что произойдет, если вы забудете разрешенные поля???
Хотя это не связанный с технологией вопрос, Seam framework позволяет вам обновлять только то, что вы хотите. Поэтому вам не нужно беспокоиться о том, какой шаблон использовать.
С уважением,
Ответ 2
A) Извлеките родительский экземпляр из Сессию снова и заменить вручную обновленные поля
это, кажется, самая функциональная версия, которую я использовал за последние несколько лет.
B) Храните ребенка где-то (httpSession?) и связать его последняя.
Я бы посоветовал это, особенно если вы хотите следовать парадигме REST, которая делает состояние стороны сервера полным no-no. И вы закончите использование кучи пространства для отдельных объектов, хотя пользователь, который инициировал сеанс, остался на кофе:)
C) Установите связь между родительским и Ребенок как неизменный.
ИМХО это тоже нехорошо, хотя он был бы пригоден для небольшого проекта с небольшой моделью устойчивости. Но даже в небольшом приложении это может привести к головной боли при попытке изменить код.
Ответ 3
Вы можете напрямую отредактировать отдельный объект, а затем снова привязать объект к сеансу, используя метод merge в сеансе.