有没有通用的方法可以
if(entity is persisted before){
entity = entity.merge();
}else{
entity.persist();
}
那么包含上述逻辑的方法到处都是安全的吗?
有没有通用的方法可以
if(entity is persisted before){
entity = entity.merge();
}else{
entity.persist();
}
那么包含上述逻辑的方法到处都是安全的吗?
如果您需要知道对象是否已经在持久化上下文中,您应该contains
使用EntityManager
.
只能EntityManager
告诉你实体是否持久化,实体没有这样的信息。
在这里您可以检查 javadoc 的contains
方法。
if (!em.contains(entity)) {
em.persist(entity);
} else {
em.merge(entity);
}
要检查当前 PersistenceContext 是否已持久化实体对象,您可以使用 EntityManager 方法contains(Object entity)
也许为时已晚,但这是我的发现!如果您有一个具有生成值的实体,则可以使用它来检查该实体是否已经在数据库中,假设您没有手动修改此值。
@Entity
public class MyEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Integer id;
// getter...
}
public class Main {
public static void main() {
MyEntity myEntity1 = new MyEntity();
MyEntity myEntity2 = em.find(MyEntity.class, 4);
em.detach(myEntity2); // or em.close()
// other stuff and modifications
// begin transaction
persistEntity(myEntity1); // will use persist()
persistEntity(myEntity2); // will use merge()
// commit transaction
}
// This will manage correctly entities in different state
public void persistEntity(MyEtity entity) {
if (myEntity.getId() != null) em.merge(entity);
else em.persist(entity);
}
}
在这种情况下使用em.contains(entity)会失败:
public static void main(){
MyEntity myEntity = em.find(MyEntity.class, 5);
em.detach(myEntity); // or em.close()
// We are going to execute persist() because the entity is detached
if (!em.contains(myEntity))
// This call will produce an exception org.hibernate.PersistentObjectException
em.persist(myEntity);
else
em.merge(myEntity);
}
尝试实现 OP 正在尝试做的事情是有性能原因的。您当然可以使用em.merge()而不是em.persist(),但并非没有成本。
对em.merge()的调用正在尝试使用SELECT查询从数据库中检索现有实体并对其进行更新。因此,如果实体从未被持久化,这将浪费一些 CPU 周期。另一方面em.persist()只会产生一个INSERT查询。