update saveorupdate java database hibernate

java - saveorupdate - sessionfactory save or update



Comportamiento de Hibernate saveOrUpdate (5)

Como se indica here , saveOrUpdate guarda una instancia transitoria generando un nuevo identificador o actualiza / vuelve a conectar las instancias separadas asociadas con su identificador actual. Más específicamente, lo hace:

  • si el objeto ya es persistente en esta sesión, no hagas nada
  • si otro objeto asociado con la sesión tiene el mismo identificador, lanza una excepción
  • si el objeto no tiene propiedad de identificador, save()
  • si el identificador del objeto tiene el valor asignado a un objeto recién instanciado, guárdelo ()
  • si el objeto tiene una <version> o <timestamp> , y el valor de la propiedad de la versión es
  • el mismo valor asignado a un objeto recién instanciado, save()
  • de lo contrario, update() el objeto

¿Alguien sabe cómo Hibernate sabe si INSERTAR o ACTUALIZAR un valor en la base de datos cuando se llama a session.saveOrUpdate() ?

Hasta ahora, solo he determinado que no depende de la información en el caché, y que la existencia de la entidad en la base de datos está determinada por la clave primaria.


Cuando use .saveOrUpdate() Hibernate comprobará si el objeto es transitorio (no tiene ninguna propiedad de identificador) y, de ser así, lo hará persistente al generarlo y asignarlo a la sesión. Si el objeto ya tiene un identificador, realizará .update() .

De la documentation :

saveOrUpdate () hace lo siguiente:

  • si el objeto ya es persistente en esta sesión, no hagas nada
  • si otro objeto asociado con la sesión tiene el mismo identificador, lanza una excepción
  • si el objeto no tiene propiedad de identificador, guárdelo ()
  • si el identificador del objeto tiene el valor asignado a un objeto recién instanciado, guárdelo ()
  • si el objeto tiene una versión con un o y el valor de la propiedad de la versión es el mismo valor asignado a un objeto recién instanciado, save () de lo contrario actualizará () el objeto

Esto se hace en base al valor de la clave primaria. Si la clave principal no está definida, su valor predeterminado será 0 para las claves sustitutas numéricas y se realizará el save . Si la clave principal está completa, invocará una update .


Si alguien no entiende realmente en teoría, entonces hay un código

MyModel sent = myDao.myDaoImpl(id); if(sent == null){ sent = **new MyModel();** // new Object sent.setXX(id); sent.setYY("Yes"); sent.setDate(new Date()); myDao.saveOrUpdate(sent); // Insert will be called }else if(! "Yes".equalsIgnoreCase(sent.getFlag())){ sent.setXX("Yes"); sent.setDate(new Date()); myDao.saveOrUpdate(sent); // Update will be called }


Tal vez sea útil citar la Biblia de Hibernate ( Java Persistence with Hibernate, 2nd ed. , Página 528):

Los usuarios más experimentados de Hibernate usan saveOrUpdate() exclusivamente; es mucho más fácil dejar que Hibernate decida qué es nuevo y qué es viejo, especialmente en una red más compleja de objetos con estado mixto. La única desventaja (no realmente grave) del exclusivo saveOrUpdate() es que a veces no puede adivinar si una instancia es vieja o nueva sin activar un SELECT en la base de datos, por ejemplo, cuando una clase se asigna con una clave compuesta natural y ninguna propiedad de versión o marca de tiempo.

¿Cómo detecta Hibernate qué instancias son antiguas y cuáles son nuevas? Una gama de opciones está disponible. Hibernate supone que una instancia es una instancia transitoria no guardada si:

  • La propiedad del identificador es null .
  • La propiedad de versión o marca de tiempo (si existe) es null .
  • Una nueva instancia de la misma clase persistente, creada internamente por Hibernate, tiene los mismos valores de identificador de base de datos que la instancia dada.
  • Proporciona un unsaved-value en el documento de mapeo para la clase, y el valor de la propiedad del identificador coincide. El atributo de unsaved-value también está disponible para los elementos de mapeo de la versión y la marca de tiempo.
  • Los datos de entidad con el mismo valor de identificador no se encuentran en la memoria caché de segundo nivel.
  • Usted suministra una implementación u org.hibernate.Interceptor y devuelve Boolean.TRUE desde Interceptor.isUnsaved() después de verificar la instancia en su código.