如何在JPA中复制Hibernate的saveOrUpdate?

在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 transcationless阅读很好,但我真的从Hibernate中缺less这种方法。 有经验的JPA开发者如何处理这个问题?

尝试使用EntityManager.merge方法 – 这是非常相似的。

Xebia的博文中有一个很好的描述:“ JPA实现模式:保存(分离)实体” 。

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

考虑创build一个新的ORM实体对象,您可以给这个数据库表中的现有行相同的数据,但除非我错了,实体pipe理器不会将它们识别为同一行,直到它们具有相同的主键,在使用自动生成的密钥的实体中,只有在进入数据库之后才能获得。

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

 /** * 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()); } }