2011-03-09 19 views
6

Estas son las secuencias que conducen a la pregunta:JPA: ¿Cuál es el comportamiento de la fusión con la colección inicializada perezosa?

  1. tengo un récord del equipo, y 3 registros en la base de datos del jugador. entidad equipo tiene una lista que está utilizando FetchType.LAZY, CascadeType.ALL
  2. El botón de búsqueda en la webui se hace clic en
  3. consulta en el lado del servidor mediante la consulta de la APP se invoca, la búsqueda de todos los registros del equipo, en este caso, solo 1 registro de la entidad del equipo devuelta desde la consulta (que tiene un proxy de la lista de entidades de jugadores)
  4. Asigna este equipo a una DTO y devuelve este DTO al webui, omitiendo el mapeo de la lista de entidades de jugadores
  5. Webui representa el DTO en un formulario html, listo para recibir modificaciones del usuario
  6. El usuario modifica las propiedades del equipo, como la fecha de f undada
  7. se hace clic en el botón Guardar de la webui
  8. La conversión de la DTO a la entidad de equipo, que se utilizará para actualizar el registro del equipo ya existente
  9. Pero en este caso, si yo fuera a utilizar el em.merge (teamEntity), el registro del equipo se actualizará, pero ¿qué pasará con la lista de jugadores? Porque al convertir de DTO a la entidad del equipo, teamEntity tiene una lista vacía de entidades de jugadores. Y después de fusionarme, noté que la teamEntity tiene 0 tamaño de detalles. Pero después de refrescar esa entidad, em.refresh (teamEntity), devolverá 3 del tamaño de detalle.

Im confundido en:

  1. ¿Por qué es el tamaño es 0 después se fusionó? Es como no representar más el registro
  2. Antes de hacer la prueba, estaba pensando que los detalles se eliminarán ya que estoy fusionando una teamEntity con un detalle vacío.

favor ilumíneme :)

Gracias!

Respuesta

9

APP Especificación dice:

La semántica de la fusionan operación aplica a una entidad X son los siguientes:

  • Si X es una entidad individual, el estado de X se copia en una instancia de entidad gestionada preexistente X 'de la misma identidad o una nueva copia administrada X' de X es creado.

  • Si X es una nueva instancia de la entidad , una nueva entidad gestionada ejemplo X 'es creado y el estado de X se copia en la nueva entidad gestionada ejemplo X'.

  • Si X es una instancia de entidad eliminado, un IllegalArgumentException se lanzada por la operación de combinación (o la transacción comprometen fallará).

  • Si X es una entidad gestionada, se ignora por la operación de fusión, sin embargo, la operación de combinación se conecta en cascada a entidades referenciadas por las relaciones de X si estas relaciones han sido anotado con la cascada valor del elemento cascade=MERGE o cascade=ALL anotación.

  • Para todos entidades Y referenciados por relaciones de X que tiene el elemento de cascada valor cascade=MERGE o cascade=ALL, Y se fusiona de forma recursiva como Y'. Para todos tal Y referenciado por X, X 'se establece en referencia Y'. (Tenga en cuenta que si X es gestionados entonces X es el mismo objeto que X ')

  • Si X es una entidad se fusionó a X', con una referencia a otra entidad Y, donde cascade=MERGE o cascade=ALL es no se especifica, la navegación de la misma asociación de X 'produce una referencia a un objeto de Y administrado' con la misma identidad persistente como Y.

Como puedes ver, no hay magia aquí. El estado de la instancia separada se copia en la instancia administrada recientemente creada. Como su instancia separada tiene una lista vacía, la instancia administrada también la tendrá.

aún más el comportamiento depende de la propiedad de la relación, ya que la representación en la base de datos refleja la parte propietaria de la relación:

  • Si Team es el lado propietario, las relaciones entre Team y Player s serán destruidos durante la descarga (pero Player en sí mismo podría sobrevivir a menos que tenga orphanRemoval = true en su relación).
  • De lo contrario, tener la lista vacía en Team no afecta a la base de datos.

Si actualiza la Team antes de lavar el contexto, todas las propiedades de Team se vuelven a escribir en los valores de la base de datos, por lo tanto, la lista de Player s se restaura (ya que la lista vacía de los jugadores no se barrió con todo).

Si llama antes de llamar a flush()refresh(), y Team es la parte propietaria, la lista estará vacía, ya que la destrucción de las relaciones se propagó a la base de datos durante flush().

+0

axtavt: ¡Gracias por la explicación! Acabo de probar todas las posibilidades que mencionó, y ahora está empezando a comprender la situación.Acerca de su extracto: "Si llama a flush() antes de llamar a refresh(), y Team es el propietario, la lista estará vacía, ya que la destrucción de relaciones se propagó a la base de datos durante flush()", será así si orphanRemoval true se usa. De lo contrario, los niños sobreviven y la actualización los restaurará en la lista de jugadores de la entidad. Gracias de nuevo ! – bertie

+0

¿Qué proveedor de JPA usas? Estoy familiarizado con Hibernate, sin JPA, que también tiene una operación de combinación y colecciones diferidas, y cuando intento leer una colección no inicializada desde una instancia separada, obtengo una excepción, no una colección vacía. Creo que es un error del proveedor. Como solución, inicialice esa colección antes de que TeamPlayer se separe. – Oliv

Cuestiones relacionadas