Tengo una relación padre-hijo donde el padre tiene la propiedad @version y debe incrementarse cada vez que cambia el padre o cualquiera de sus hijos.
@Entity class Parent{ @OneToMany(mappedBy = "parent", ...) Set<Child> children; @Version int version; } @Entity class Child{ @ManyToOne Parent parent; }Para archivar esto, bloqueo al padre en modo OPTIMISTIC_FORCE_INCREMENT, cada vez que agrego, modifico o elimino un hijo.
entityManager.lock(parent, LockModeType.OPTIMISTIC_FORCE_INCREMENT); // modify childInmediatamente antes de que se complete la transacción, hibernate genera una declaración como esta
/* forced version increment */ update "PARENT" set "VERSION"=? where "PARENT_ID"=? and "VERSION"=?La versión en la base de datos se incrementa correctamente mientras que el 2nd-Level-Cache no se actualiza. Si selecciono el padre, se cargará desde 2nd-Level-Cache y todavía obtengo la versión anterior, podría actualizarlo o desalojarlo de 2nd-Level-Cache, pero no se siente bien, simplemente tiene que ser actualizado en coherencia con la base de datos.
Probé Infinispan y EHCache, que se comportan igual, así que creo que es un problema de hibernación.
Esta es también la razón por la que el patrón RootAware de Vlad Mihalcea no funciona en combinación con 2nd-Level-Cache. Consulte https://vladmihalcea.com/how-to-increment-the-parent-entity-version-whenever-a-child-entity-gets-modified-with-jpa-and-hibernate/
Vea este comentario: https://stackoverflow.com/a/31003719/9354242 Como sugerí en este comentario, agregué una columna @LastModifiedDate al elemento principal y la actualicé cada vez que modifiqué un elemento secundario. En lugar de OPTIMISTIC_FORCE_INCREMENT tendré que usar OPTIMISTIC como LockModeType y está funcionando, tanto 2nd-Level-Cache como la base de datos tienen el número de versión correcto, pero no creo que sea una solución muy buena ya que todos los desarrolladores deben conocer y hay una gran probabilidad de que alguien en algún lugar lo olvide. Además, es malo agregar una columna como esta solo como una solución.
Gracias por adelantado
¿Cuál es su estrategia de caché para la clase Parent ? ¿Podría ser READ_ONLY? Intente agregar una anotación de caché
@Cache(usage = READ_WRITE) @Entity class Parent... a su entidad y ver si la situación mejora!