Как вы можете копировать saveOrUpdate Hibernate в JPA?
В JPA есть ли способ реплицировать поведение saveOrUpdate в Hibernate,
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 ответа
Попробуйте использовать EntityManager.merge
Метод - это очень похоже.
Отличное описание различий в блоге Xebia: " Шаблоны реализации JPA: сохранение (отсоединение) сущностей".
Проблема метода, описанного в статье, с которой связан Паблоджим, заключается в том, что он не очень хорошо обрабатывает автоматически сгенерированные первичные ключи.
Рассмотрим создание нового объекта сущности 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());
}
}