объединение отдельного или нового объекта с существующим объектом в hibernate / jpa - PullRequest
9 голосов
/ 21 января 2011

Когда бизнес-уровень создает новый объект, который логически представляет экземпляр существующего объекта, который должен быть обновлен (скажем, они используют один и тот же бизнес-ключ), является ли этот метод объединения плохой практикой?

public User add(User user){

    User existingUser = getUserDao().findByBusinessKey(user.getBusinessKey(), false);
    user.setId(existingUser.getId());

    user = getUserDao().merge(user);

    return user;
}

Я спрашиваю, потому что установка идентификатора явно для отсоединенного объекта кажется мне довольно странной, но даже при том, что метод equals и hashcode объекта User реализованы надлежащим образом, установка идентификатора здесь - единственный способ обеспечить слияние.

Есть ли лучшая практика?

Есть ли у этого метода определенные недостатки, которые меня потом укусят?

Спасибо, что взглянули!

Ответы [ 2 ]

2 голосов
/ 26 января 2011

Этот код будет работать , но установка идентификатора явно на отдельном объекте не обязательна.Типичное приложение Hibernate имеет метод save, который обрабатывает два случая:

  1. Пользователь хотел создать нового пользователя, поэтому приложение создает объект User с 'null' в качестве идентификатора.
  2. Пользователь запросил список пользователей и выбирает его для редактирования.В этом случае приложение выполняет запрос и передает объект в метод «save».У объекта будет идентификатор, и код будет применять к нему новые значения.

Похоже, что-то в вашем коде не выполняет второй случай обычным способом.Если объект «пользователь» получен из какого-то предыдущего запроса Hibernate (вызванного нажатием пользователем «изменить пользователя» или что-то в этом роде), то у него уже будет идентификатор.Таким образом, необходим только вызов merge(user).

Я обычно делаю что-то вроде этого:

if (user.getId() == null)
  em.persist(user);
else
  user = em.merge(user);

Затем я добавляю код для обработки проблем с оптимистической блокировкой (другой сеанс обновил объект) иуникальные проблемы с ограничениями (другой сеанс пытался что-то сохранить с тем же бизнес-ключом).

Каркасы, такие как Seam, могут сделать это еще проще, поскольку они распространяют сеанс Hibernate между методами bean-компонента контроллера.Так что даже «слияние» не нужно.

0 голосов
/ 23 января 2011

Если ваша сущность является отдельной сущностью, единственное, что вам действительно нужно сделать, это вызвать entityManager.merge (user). Вам не нужно выполнять какой-либо метод поиска. Если ваша сущность не отделена, а скорее нова (для нее не указан идентификатор), вы должны найти соответствующую сущность в базе данных до выполнения каких-либо операций по модификации этой сущности и объединить ее впоследствии. то есть:

User user = userDao.findBySomething(Criteria c);

//stuff that modifies user 

user = userDao.merge(user);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...