mundo - java and hibernate
¿Cómo detecta Hibernate el estado sucio de un objeto de entidad? (4)
¿Está utilizando algún tipo de modificación de códigos de bytes en las clases originales?
O, tal vez Hibernate obtenga el estado sucio al comparar el objeto dado con la versión previamente conservada?
Tengo un problema con los hashCode()
y equals()
para objetos complicados. Creo que sería muy lento calcular el código hash si el objeto tiene miembros de colección, y las referencias cíclicas también son un problema.
Si Hibernate no va a usar hashCode()
/ equals()
para verificar el estado sucio, supongo que no debería usar equals()
/ hashCode()
para el objeto de entidad (no el objeto de valor), pero también me temo que si mismo operador ( ==
) no es suficiente.
Entonces, las preguntas son:
¿Cómo sabe Hibernate si se cambia una propiedad de un objeto?
¿Sugiere anular los
hashCode()
/equals()
para objetos complicados? ¿Qué pasa si contienen referencias cíclicas?Y también,
¿Sería
hashCode()
/equals()
con solo el campoid
?
Es simple-- cuando carga / obtiene el objeto entidad por id y luego establece sus nuevos valores de campo por el método setter y cierra la sesión sin llamar al método update () . luego hibernate actualiza automáticamente el valor modificado en la tabla sin afectar a otros campos. y al mismo tiempo el objeto de entidad está en estado sucio .
Hibernate realiza una comprobación campo por campo para determinar la suciedad de una entidad.
Entonces hashCode / equals no entran en la imagen en absoluto.
En realidad, la comprobación sucia de campo por campo realizada por Hibernate puede ser bastante costosa en términos de rendimiento.
Por lo tanto, proporciona interfaces como Strategy o Interceptor.findDirty () para manejar el mismo.
La publicación siguiente explica esto en mayor detalle (junto con algunas ideas para aplicaciones para optimizarlo completamente): http://prismoskills.appspot.com/lessons/Hibernate/Chapter_20_-_Dirty_checking.jsp
Hibernate usa una estrategia llamada inspección , que es básicamente esto: cuando un objeto se carga desde la base de datos, se guarda una instantánea de la misma en la memoria. Cuando se vacía la sesión, Hibernate compara la instantánea almacenada con el estado actual. Si difieren, el objeto se marca como sucio y se pone en cola un comando SQL adecuado. Si el objeto aún es transitorio, siempre está sucio.
Fuente: libro Hibernate en acción (apéndice B: estrategias de implementación de ORM)
Sin embargo, es importante notar que la verificación sucia de Hibernate es independiente de los métodos equals / hascode . Hibernate no mira en absoluto estos métodos (excepto cuando usa java.util.Set, pero esto no está relacionado con la comprobación sucia, solo con la API de colecciones). La instantánea de estado que mencioné anteriormente es algo similar a una matriz de valores. Sería una decisión muy mala dejar ese aspecto central del marco en manos de los desarrolladores (para ser honesto, los desarrolladores no deberían preocuparse por la verificación sucia). No hace falta decir que equals / hascode se puede implementar de muchas maneras según sus necesidades. Te recomiendo que leas el libro citado, allí el autor discute las estrategias de implementación equals / hascode. Lectura muy perspicaz.
El mecanismo de verificación sucia por defecto de Hibernate hará coincidir todas las propiedades mapeadas de todas las entidades actualmente conectadas con sus valores iniciales de tiempo de carga.
Puede visualizar mejor este proceso en el siguiente diagrama: