¿Es posible cambiar una instancia de entidad versionada y obtener la versión que se va a incrementar sin usar flush? Porque, por lo que he leído, tengo miedo de que el color no sea una buena práctica porque tiene un impacto negativo en el rendimiento o incluso en la corrupción de datos. No estoy seguro: DFusionar y obtener la versión actualizada sin descarga?
Aquí hay un código simple y también la salida como el comentario:
/*
Hibernate: select receivingg0_.id as id9_14_, receivingg0_.creationDate as creation2_9_14_, ... too long
the version before modification : 16
the version after modification : 16
after merge the modification, the version is : 16
Hibernate: update ReceivingGood set creationDate=?, modificationDate=?, usercreate_id=?, usermodify_id=?, ... too long
after flushing the modification, the version is finally : 17
*/
public void modifyHeaderAndGetUpdatedVersion() {
String id = "3b373f6a-9cd1-4c9c-9d46-240de37f6b0f";
ReceivingGood receivingGood = em.find(ReceivingGood.class, id);
System.out.println("the version before modification : " + receivingGood.getVersion());
receivingGood.setTransactionNumber("NUM001xyz");
System.out.println("the version after modification : " + receivingGood.getVersion());
receivingGood = em.merge(receivingGood);
System.out.println("after merge the modification, the version is : " + receivingGood.getVersion());
em.flush();
System.out.println("after flushing the modification, the version is finally : " + receivingGood.getVersion());
}
En mi prueba, la versión obtuve incrementa después de la descarga. La instancia devuelta desde la operación de fusión no tiene la versión incrementada.
Pero en mi caso, me gustaría devolver la entidad a mi webui en forma de DTO, y la entidad debe tener la versión después del enjuague/confirmación antes de convertirla en DTO y devolverla a la interfaz de usuario para ser prestado Y luego la interfaz de usuario podría tener la última versión, y pasará esta versión para la próxima presentación.
¿Hay alguna manera en la que pueda obtener la última versión sin hacer flush?
¡Gracias!
ACTUALIZACIÓN
En mi experiencia, incrementando de este manual puede ser problemático, ya que se puede ver en este ejemplo a continuación. En este ejemplo, tenemos 2 descargas.
El primero es sincronizar los cambios a la conexión db, de modo que una llamada a procedimiento almacenado desde la misma conexión pueda ver los cambios realizados desde el entityManager.
Se llama a la segunda descarga para obtener la versión final. Y podemos ver que esto es incrementado dos veces. Por lo tanto, obtener la versión solo del incremento manual sin vaciado no funcionaría en esta condición, ya que tenemos que contar realmente cuántas descargas se están realizando.
/*
Hibernate: select receivingg0_.id as id9_14_, receivingg0_.creationDate as creation2_9_14_, .. too long
the version before modification : 18
the version after modification : 18
after merge the modification, the version is : 18
now flushing the modification, so that the stored procedure call from the same connection can see the changes
Hibernate: update ReceivingGood set creationDate=?, modificationDate=?, usercreate_id=?, .. too long
after flushing the modification, the version is : 19
Hibernate: update ReceivingGood set creationDate=?, modificationDate=?, usercreate_id=?, .. too long
after the second flush, the version got increased again into : 20
*/
public void modifyHeaderAndGetUpdatedVersionWith2Flushes() {
String id = "3b373f6a-9cd1-4c9c-9d46-240de37f6b0f";
ReceivingGood receivingGood = em.find(ReceivingGood.class, id);
System.out.println("the version before modification : " + receivingGood.getVersion());
//auditEntity(receivingGood, getUser("3978fee3-9690-4377-84bd-9fb05928a6fc"));
receivingGood.setTransactionNumber("NUM001xyz");
System.out.println("the version after modification : " + receivingGood.getVersion());
receivingGood = em.merge(receivingGood);
System.out.println("after merge the modification, the version is : " + receivingGood.getVersion());
System.out.println("now flushing the modification, so that the stored procedure call from the same connection can see the changes");
em.flush();
System.out.println("after flushing the modification, the version is : " + receivingGood.getVersion());
receivingGood.setTransactionNumber("NUM001abc");
em.flush();
System.out.println("after the second flush, the version got increased again into : " + receivingGood.getVersion());
}
¿Esto significa que realmente no tienen que depender de la descarga al final para obtener la última versión modificada de la entidad?
ACTUALIZACIÓN 2
Aquí es un simple ejemplo de un método de servicio que actualizará la entidad ReceivingGood y debe devolver un DTO que tiene la versión más reciente.
public ReceivingGoodDTO update(ReceivingGood entity) {
// merge it
entity = entityManager.merge(entity);
// the version is not incremented yet, so do the flush to increment the version
entityManager.flush(); // if i dont do this, the dto below will get the unincremented one
// use a mapper, maybe like dozer, to copy the properties from the entity to the dto object, including the newest version of that entity
ReceivingGoodDTO dto = mapper.map(entity, dto);
return dto;
}
y aquí es un ejemplo que hace uso de ese método:
@Transactional
public ReceivingGoodDTO doSomethingInTheServiceAndReturnDTO() {
// do xxx ..
// do yyy ..
dto = update(entity);
return dto; // and the transaction commits here, but dto's version isnt increased because it's not a managed entity, just a plain POJO
}
@partenon: entiendo cómo funciona el enjuague y la confirmación, y cómo la versión se incrementó por ellos. Pero aún leeré el libro que recomendó :-) De todos modos, he actualizado mi publicación original para algunas inquietudes adicionales con respecto al incremento manual. Gracias, como siempre. – bertie
Acabo de actualizar la respuesta para abordar sus nuevas inquietudes :-) – jpkrohling
@partenon: Entonces, finalmente puedo concluir que, para crear un DTO dentro de la transacción activa que refleja la entidad con la última versión, realmente tengo que hacer una enjuagar(). Gracias ! – bertie