当业务层创建一个新实体时,它在逻辑上表示应该更新的现有实体的实例(假设它们共享相同的业务 key ),这种方法是否合并了不良做法?
public User add(User user){
User existingUser = getUserDao().findByBusinessKey(user.getBusinessKey(), false);
user.setId(existingUser.getId());
user = getUserDao().merge(user);
return user;
}
我问是因为在分离的实体上显式设置 ID 对我来说感觉很奇怪,但即使适本地实现了用户实体的 equals 和 hashcode 方法,在这里设置 ID 也是确保合并发生的唯一方法.
有更好的做法吗?
这种方法是否有特定的缺点会影响我以后的工作?
感谢您的关注!
最佳答案
该代码将工作,但没有必要在分离的实体上显式设置 ID。一个典型的 Hibernate 应用程序有一个处理两种情况的“保存”方法:
- 用户想要创建一个新用户,因此该应用创建了一个 ID 为“null”的用户对象。
- 用户查询了用户列表,并选择了一个进行编辑。在这种情况下,应用程序执行查询并将对象传播到“保存”方法。该对象将有一个 ID,代码将为其应用新值。
看起来你的代码中的某些东西没有以典型的方式处理第二种情况。如果“用户”对象来自某个先前的 Hibernate 查询(由用户单击“编辑用户”或类似的东西触发),那么它已经有一个 ID。因此,只需要 merge(user)
调用。
我通常会这样做:
if (user.getId() == null)
em.persist(user);
else
user = em.merge(user);
然后我添加代码来处理乐观锁定问题(另一个 session 更新了对象)和唯一约束问题(另一个 session 尝试使用相同的业务 key 来保存某些内容)。
Seam 等框架可以使这更简单,因为它们在 Controller bean 方法之间传播 Hibernate session 。因此,甚至不需要“合并”。
关于java - 在 hibernate/jpa 最佳实践问题中将分离的或新的实体与现有实体合并,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4755520/