java - 在 hibernate/jpa 最佳实践问题中将分离的或新的实体与现有实体合并

标签 java hibernate design-patterns jpa persistence

当业务层创建一个新实体时,它在逻辑上表示应该更新的现有实体的实例(假设它们共享相同的业务 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 应用程序有一个处理两种情况的“保存”方法:

  1. 用户想要创建一个新用户,因此该应用创建了一个 ID 为“null”的用户对象。
  2. 用户查询了用户列表,并选择了一个进行编辑。在这种情况下,应用程序执行查询并将对象传播到“保存”方法。该对象将有一个 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/

相关文章:

java - 在 Azure 数据工厂中设置不带冒号的时间格式 (Java SimpleDateFormat)

java - Hibernate session REST 性能/安全性

java - BeanCreationExceptionEntityManagerFactoryNoClassDefFoundErrorValidatorFactory

java - LockManager - 想法和API

java - 优化期间会使用 Java 内联方法吗?

java - java.lang.String.length处的NullPointerException(String.java :611))

Java Final 类或私有(private)构造函数

java - 使用 @OneToMany 或 @ManyToMany 定位未映射的类

javascript - 在 JavaScript 中以模块模式扩展模块

python - 在哪里存储现场数据以及如何提供对其的访问?