Подтвердить что ты не робот

Лучший способ обновить некоторые поля отдельного объекта в 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 в отношении, я могу обновить любое родительское поле, не беспокоясь о потере ребенка. В любом случае, это довольно ограничительно, и отношения никогда не будут обновлены.

Итак, как вы думаете, лучший способ решить эту ситуацию?

Заранее благодарю вас!

4b9b3361

Ответ 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 в сеансе.