Лучший способ обновить некоторые поля отдельного объекта в Hibernate?
Мне было интересно, как лучше всего обновить некоторые поля детализированного объекта, используя HB на Java. Особенно, когда объект имеет атрибуты дочерних объектов. Например (аннотации удалены, а количество полей уменьшено для уменьшения шума):
public class Parent {
int id;
String field2;
...
Child child;
}
public class Child {
int id;
String field3;
}
При обновлении Parent в веб-приложении MVC я мог бы вызвать родительский экземпляр с помощью Session.get (Parent.class, 123), использовать его для заполнения формы и ее отображения. Нет DTO, только отсоединенный родительский элемент передается в представление и связывается с формой. Теперь я хочу только разрешить пользователю обновлять атрибут field2 родителя. Поэтому, когда пользователь публикует форму, я получаю экземпляр Parent с заполненными 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. Также становится ужасно, если количество полей для обновления увеличивается.
Б) Храните Дитя где-нибудь (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) Установите отношение между Родителем и Ребенком как неизменное. Используя в связке updatable=false, я могу обновить любое родительское поле, не беспокоясь о потере потомка. Во всяком случае, это довольно ограничительно, и отношения никогда не будут обновлены.
Итак, что вы думаете, это лучший способ решить эту ситуацию?
Заранее спасибо!
3 ответа
После загрузки родительского объекта вы сказали
Теперь я хочу разрешить пользователю обновлять атрибут field2 родительского элемента.
В зависимости от варианта использования вы можете использовать объект UpdateableParent
public class UpdateableParent {
private String field2;
// getter's 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 позволяют вам установить свойство позволено полей). Что произойдет, если вы забудете некоторые разрешенные поля???
Хотя это не вопрос, связанный с технологиями, платформа Seam позволяет обновлять только то, что вы хотите. Так что вам не нужно беспокоиться о том, какой шаблон использовать.
С уважением,
A) Извлеките родительский экземпляр снова из сеанса и замените вручную обновленные поля.
кажется, это самая функциональная версия, которую я использовал за последние несколько лет.
Б) Храните Дитя где-нибудь (httpSession?) И связывайте его последним.
Я бы посоветовал против этого, особенно если вы хотите следовать парадигме REST, которая делает состояние на стороне сервера полным нет-нет. И в итоге вы будете использовать пространство кучи для отдельных объектов, хотя пользователь, который инициировал сеанс, ушел на кофе:)
C) Установите отношение между Родителем и Ребенком как неизменное.
ИМХО, это тоже не очень хороший способ, хотя он подходит для небольшого проекта с небольшой моделью персистентности. Но даже в небольшом приложении это может привести к головной боли при попытке изменить код.
Вы можете изменить отсоединенный объект напрямую, а затем снова присоединить объект к сеансу, используя метод слияния в сеансе.