如何在JPA中复制Hibernate的saveOrUpdate?

时间:2009-07-16 18:41:01

标签: java hibernate jpa persistence

在JPA中,有什么方法可以复制Hibernate的saveOrUpdate behavior

saveOrUpdate

public void saveOrUpdate(Object object)
                  throws HibernateException

    Either save(Object) or update(Object) the given instance, depending upon resolution of the unsaved-value checks (see the manual for discussion of unsaved-value checking).

    This operation cascades to associated instances if the association is mapped with cascade="save-update".

    Parameters:
        object - a transient or detached instance containing new or updated state 
    Throws:
        HibernateException
    See Also:
        save(Object), update(Object)

基本上检查对象是否已存在于数据库中,并根据需要更新该对象或保存对象的新实例。

JPA无抄写读取很好,但我真的很想从Hibernate中获取这个方法。经验丰富的JPA开发人员如何处理这个问题?

2 个答案:

答案 0 :(得分:29)

尝试使用EntityManager.merge方法 - 这非常相似。

对Xebia的博文中的差异进行了很好的描述:“JPA Implementation Patterns: Saving (Detached) Entities。”

答案 1 :(得分:4)

Pablojim链接到的文章中概述的方法的问题是它不能很好地处理自动生成的主键。

考虑创建一个新的ORM实体对象,你可以给它提供与数据库表中现有行相同的数据,但除非我弄错了,否则实体管理器不会将它们识别为同一行,直到它们具有相同的主键,在使用自动生成的键的实体中,在进入数据库之前无法获取。

这是我目前为这种情况所做的工作;

/**
 * Save an object into the database if it does not exist, else return
 * object that exists in the database.
 *
 * @param query query to find object in the database, should only return
 * one object.
 * @param entity Object to save or update.
 * @return Object in the database, whither it was prior or not.
 */
private Object saveOrUpdate(Query query, Object entity) {
    final int NO_RESULT = 0;
    final int RESULT = 1;

    //should return a list of ONE result, 
    // since the query should be finding unique objects
    List results = query.getResultList();
    switch (results.size()) {
        case NO_RESULT:
            em.persist(entity);
            return entity;
        case RESULT:
            return results.get(0);
        default:
            throw new NonUniqueResultException("Unexpected query results, " +
                    results.size());
    }
}