JPA:检查实体对象是否已被持久化

时间:2013-04-18 20:00:16

标签: java java-ee jpa ejb

是否有一般方法可以

 if(entity is persisted before){
     entity = entity.merge();
 }else{
     entity.persist();
 }

所以包含上述逻辑的方法到处都是安全的吗?

3 个答案:

答案 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 查询。