在JPA中如何复制Hibernate的saveOrUpdate功能?

46

在JPA中,是否有办法复制Hibernate的saveOrUpdate行为

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开发人员如何处理这种情况?


检查一下 "主键" 是否为空呢? - Rémy
2个回答

37

7
我在这里得出的重要结论是:“当更新现有实体时,我们不会调用任何EntityManager方法;JPA提供程序将在刷新或提交时自动更新数据库。” - James McMahon
2
链接已失效。这是新的链接:http://blog.xebia.com/jpa-implementation-patterns-saving-detached-entities/ - Dmitry
此页面已不存在,404 页面未找到。 - Yashpal
1
https://xebia.com/jpa-implementation-patterns-saving-detached-entities/ ;-) - emeraldjava

5
这篇文章中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());
    }
}

1
merge和saveOrUpdate表面上看起来相似,但并不相同。它们的语义有重要的区别。 - skaffman
@skaffman,你认为我的方法有缺陷吗?如果有的话,能否提供一些建设性的批评意见。对于这个JPA的东西,我还是一个新手。 - James McMahon
刚发现这个旧帖子,我正在实现类似的解决方案,只不过使用新的Java ENUMS。谢谢。 - oberger

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接