java - saveorupdate - jpa update entity
¿Cómo se puede replicar SaveOrUpdate de Hibernate en JPA? (2)
En JPA, ¿hay alguna manera de que pueda replicar el comportamiento saveOrUpdate de 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)
que esencialmente verifica si el objeto ya existe en la base de datos y actualiza ese objeto según sea necesario o guarda una nueva instancia del objeto.
Las lecturas sin traducción JPA son agradables, pero realmente me falta este método de Hibernate. ¿Cómo manejan esto los desarrolladores experimentados de JPA?
El problema con el método descrito en el artículo al que Pablojim se relacionó es que no maneja muy bien las claves primarias generadas automáticamente.
Considere la creación de un nuevo objeto entidad ORM, puede darle los mismos datos que una fila existente en la tabla de la base de datos, pero a menos que esté equivocado, el administrador de la entidad no los reconoce como la misma fila hasta que tengan la misma clave primaria , que en una entidad que utiliza claves generadas automáticamente, no puede obtener hasta que vaya a la base de datos.
Aquí está mi trabajo actual para esa situación;
/**
* 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());
}
}
Intenta usar el método EntityManager.merge
: esto es muy similar.
Hay una excelente descripción de las diferencias en el blogpost de Xebia: " Patrones de implementación de JPA: Entidades de ahorro (separadas) ".