Respecto al problema de hibernación que encontraron mis colegas ayer. Es lo más básico de hibernar. Entiendo que muchas personas se han encontrado con este problema y es muy común, pero a menudo se confunden al encontrarlo.
Para profundizar la impresión, sepa qué es y por qué es así.
Después de eso, simplemente utilicé el marco de Hibernate original para realizar algunas verificaciones, abrí la consola de impresión SQL de ejecución y llegué a la conclusión:
La premisa es que en medio de la misma transacción:
1. Use la declaración SQL, session.createSQLQuery(sql).executeUpdate(); para insertar, y la estación de salida imprimirá la declaración de inserción SQL, luego use la declaración SQL para realizar session.createSQLQuery(sql).uniqueResult(); ; y también se imprimirá la consulta SQL, no hay problema y se pueden consultar los datos.
2. Utilice hibernación para encapsular la operación y utilice session.save(entity); para insertar, la consola de salida no imprime la declaración SQL insertada. Luego utilice el método session.get(entity,id); Tampoco imprime la declaración de consulta SQL, pero se pueden consultar los datos. Cuando se ejecuta la declaración de confirmación de la transacción, se imprime la declaración SQL insertada
3. Utilice session.save(entity) de hibernate para insertar y luego utilice la declaración "HQL" para consultar. El efecto es el mismo que el segundo punto anterior.
4. Utilice session.save(entity) de hibernación para insertar, pero la consola de salida no imprime la declaración SQL insertada. Luego use la declaración SQL para realizar session.createSQLQuery(sql).uniqueResult(); y se imprimirá la declaración de consulta SQL. Ocurrió un problema, no se pudieron consultar datos. En este caso, utilice el método session.flush(), ejecute el método flush() antes de realizar la consulta y la consola de salida imprimirá la declaración SQL insertada. Si vuelves a consultar tendrás datos.
Una vez completada la verificación, verifiqué la información anterior. Con respecto al cuarto punto, apareció con frecuencia durante el proceso de desarrollo. Creo que muchas personas lo han encontrado, pero muchas personas continúan confundidas. Esto sólo profundizó la impresión.
Desde la consola de impresión SQL, podemos ver el proceso de funcionamiento de un método básico de guardado en hibernación:
1. Determine si la instancia que se va a guardar ya está en un estado persistente y, en caso contrario, colóquela en la caché;
2. Planifique una instrucción SQL de inserción basada en la instancia que se guardará. Tenga en cuenta que solo se planifica y no se ejecuta;
3. La instrucción de inserción planificada previamente se ejecuta cuando se confirma la transacción;
Reemplace tx.commit() con session.flush. En este momento, el control imprime la declaración de inserción, pero no se agregan nuevos registros a la base de datos;
La función principal del método de descarga es limpiar el caché y forzar la sincronización de la base de datos con el caché de Hibernate para garantizar la coherencia de los datos. Su acción principal es enviar una serie de declaraciones SQL a la base de datos y ejecutar estas declaraciones SQL, pero no las enviará a la base de datos. El método de confirmación primero llamará al método de descarga y luego confirmará la transacción. Esta es la razón por la que el registro no se inserta en la base de datos cuando simplemente llamamos a vaciar, porque las actualizaciones de la base de datos no se guardarán hasta que se confirme la transacción. Debido a que el método de confirmación llama implícitamente a Flush, generalmente no llamamos explícitamente al método Flush.
Este es el mecanismo de descarga de hibernación. En el proceso de actualizar y guardar algunos objetos complejos, es necesario considerar si los cambios en el orden de las operaciones de la base de datos y si los vaciados retrasados tienen un impacto en los resultados del programa. Si realmente hay un impacto, puede agregar vaciar donde necesite mantener el orden de las operaciones para obligar a Hibernate a vaciar las operaciones registradas en el caché en la base de datos. Esto puede no parecer bonito, pero es muy efectivo.
Pregunta: El método session.save se guarda en la memoria caché y SQL no puede encontrarlo consultando directamente la base de datos.
Después del método flush(), se imprimirá el SQL ejecutado, pero aún no está en la base de datos. La consulta SQL directa puede encontrar los datos.
1. ¿Dónde se almacenan los datos de la entidad después de vaciar()? El caché es el mismo que el método save(), por lo que SQL no debería poder obtenerlo.
2. Dado que los datos no ingresaron a la base de datos después del método de descarga, SQL se puede consultar directamente usando session.createSQLQuery (sql) para consultar. ¿Cuál es el lugar donde está consultando?