是否有一般方法可以
if(entity is persisted before){
entity = entity.merge();
}else{
entity.persist();
}
所以包含上述逻辑的方法到处都是安全的吗?
答案 0 :(得分:17)
如果您需要知道持久化上下文中的对象,则应使用contains
的{{1}}方法。
只有EntityManager
可以告诉您实体是否已保留,实体没有此类信息。
您可以在此检查contains
method的javadoc。
EntityManager
答案 1 :(得分:2)
要检查当前PersistenceContext是否已保留实体对象,您可以使用EntityManager方法contains(Object entity)
答案 2 :(得分:1)
也许为时已晚,但这是我的发现! 如果您有一个带有生成值的实体,则可以使用它来检查该实体是否已存在于数据库中,前提是您无需手动修改该值。
@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 查询。