简体   繁体   English

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

[英]merging a detached or new entity with an existing entity in hibernate/jpa best practice question

When the business layer creates a new entity, which logically represents an instance of an existing entity that should be updated (say they share the same business key), is this method of merging bad practice? 当业务层创建一个新实体时,逻辑上表示应该更新的现有实体的实例(比如它们共享相同的业务键),这种合并错误做法的方法是什么?

public User add(User user){

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

    user = getUserDao().merge(user);

    return user;
}

I ask because setting the ID explicitly on the detached entity feels pretty strange to me, but even though the equals and hashcode method of the User entity are appropriately implemented, setting the ID here is the only way to ensure the merge takes place. 我问,因为在分离的实体上显式设置ID对我来说感觉很奇怪,但即使User实体的equals和hashcode方法被适当地实现,在这里设置ID是确保合并发生的唯一方法。

Is there a better practice? 有更好的做法吗?

Are there specific drawbacks to this method that would bite me later on? 这种方法有什么特殊的缺点,以后会咬我吗?

Thanks for taking a look! 谢谢参观!

That code will work , but setting the ID explicitly on the detached entity should not be necessary. 该代码将起作用 ,但不应该在分离的实体上显式设置ID。 A typical Hibernate app have a 'save' method that handles two cases: 典型的Hibernate应用程序有一个“保存”方法,可以处理两种情况:

  1. The user wanted to create a new User, so the app creates a User object with 'null' as the ID. 用户想要创建一个新用户,因此应用程序创建一个User对象,其中“null”作为ID。
  2. The user queried for a list of users, and is selecting one for edit. 用户查询用户列表,并选择一个用于编辑。 In this case the app does a query and propagates the object to the 'save' method. 在这种情况下,应用程序执行查询并将对象传播到“保存”方法。 The object will have an ID and the code will apply new values to it. 该对象将具有ID,代码将向其应用新值。

Looks like something in your code isn't doing the second case in the typical way. 看起来代码中的某些内容并没有以典型方式执行第二种情况。 If the 'user' object comes from some prior Hibernate query (triggered by the user clicking 'edit user' or something like that), then it will already have an ID. 如果'user'对象来自某些先前的Hibernate查询(由用户单击'edit user'或类似的东西触发),那么它将具有ID。 Thus, only the merge(user) call is needed. 因此,只需要merge(user)调用。

I usually do something like this: 我通常做这样的事情:

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

Then I add code to handle optimistic locking issues (another session updated the object) and unique constraint issues (another session tried to persist something with the same business key). 然后我添加代码来处理乐观锁定问题(另一个会话更新了对象)和唯一约束问题(另一个会话尝试使用相同的业务键持久化)。

Frameworks such as Seam can make this even simpler because they propagate the Hibernate session between the controller bean methods. 像Seam这样的框架可以使这更简单,因为它们在控制器bean方法之间传播Hibernate会话。 So even the 'merge' is not needed. 所以即使是'合并'也不需要。

If your entity is a detached entity the only thing u really need to do is to invoke entityManager.merge(user). 如果您的实体是一个分离的实体,那么您真正需要做的就是调用entityManager.merge(user)。 You dont need to exec any finder method. 你不需要执行任何finder方法。 If your entity is not detached but rather new (it does not have id specified) you should find appropriate entity in the database prior performing any modification operations on that entity and merge it afterwards. 如果您的实体不是分离的而是新的(它没有指定id),您应该在对该实体执行任何修改操作之前在数据库中找到适当的实体,然后将其合并。 ie: 即:

User user = userDao.findBySomething(Criteria c);

//stuff that modifies user 

user = userDao.merge(user);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Hibernate:将现有的子实体添加到具有 OneToMany 双向关系的新实体并持久化(“分离的实体传递给持久化”) - Hibernate: add existing child entity to new entity with OneToMany bidirectional relationship and persist it ('detached entity passed to persist') Hibernate JPA:传递给持久化的分离实体 - Hibernate JPA: detached entity passed to persist JPA / Hibernate实体类和同步的最佳实践是什么? - What is the best practice for JPA/Hibernate entity classes and synchronization? Hibernate更新实体最佳做法 - Hibernate update entity best practice JPA:关于在删除实体之前合并实体的问题 - JPA: question about merging an entity before removing it JPA坚持与现有实体关系的新实体 - JPA persist new entity with relationship to existing entity @ManyToOne 错误 - JPA/Hibernate 分离实体传递到持久化 - Error with @ManyToOne - JPA/Hibernate Detached Entity Passed to Persist 使用Spring Data / JPA / Hibernate和分离的实体测试保存调用 - Test save call using Spring Data/JPA/Hibernate with detached entity PersistentObjectException:分离实体传递给 JPA 和 Hibernate 持久抛出 - PersistentObjectException: detached entity passed to persist thrown by JPA and Hibernate SPRING JPA-org.hibernate.PersistentObjectException:传递给持久化的分离实体: - SPRING JPA - org.hibernate.PersistentObjectException: detached entity passed to persist:
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM