Этот код будет работать , но установка идентификатора явно на отдельном объекте не обязательна.Типичное приложение Hibernate имеет метод save, который обрабатывает два случая:
- Пользователь хотел создать нового пользователя, поэтому приложение создает объект User с 'null' в качестве идентификатора.
- Пользователь запросил список пользователей и выбирает его для редактирования.В этом случае приложение выполняет запрос и передает объект в метод «save».У объекта будет идентификатор, и код будет применять к нему новые значения.
Похоже, что-то в вашем коде не выполняет второй случай обычным способом.Если объект «пользователь» получен из какого-то предыдущего запроса Hibernate (вызванного нажатием пользователем «изменить пользователя» или что-то в этом роде), то у него уже будет идентификатор.Таким образом, необходим только вызов merge(user)
.
Я обычно делаю что-то вроде этого:
if (user.getId() == null)
em.persist(user);
else
user = em.merge(user);
Затем я добавляю код для обработки проблем с оптимистической блокировкой (другой сеанс обновил объект) иуникальные проблемы с ограничениями (другой сеанс пытался что-то сохранить с тем же бизнес-ключом).
Каркасы, такие как Seam, могут сделать это еще проще, поскольку они распространяют сеанс Hibernate между методами bean-компонента контроллера.Так что даже «слияние» не нужно.