es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Hibernate ignora los milisegundos en la consulta.

Tengo una aplicación Spring Boot con JPA, que utiliza la especificación Spring para construir una instrucción select con tiempo incluyendo milisegundos. Necesito ser capaz de encontrar datos entre dos rangos de tiempo teniendo en cuenta los milisegundos.

La base de datos es PostgreSQL con un tipo de campo de tiempo. El tipo de campo de entidad Hibernate es LocalTime. Por ejemplo, cuando paso el rango de tiempo 09:00:01.000 y 09:00:00.203, puedo ver registros que están antes en el tiempo que 09:00:00.203. Esto me indica que algo ignora el 203 y va a las 09:00:00.

Cuando ejecuto la aplicación, SqlStatementLogger me muestra SQL y parámetros adecuados, como se muestra a continuación.

y quoteentit0_.action_time<=?
y quoteentit0_.action_time>=?

parámetro de enlace [3] como [TIME] – [09:00:01]
parámetro de enlace [4] como [TIME] – [09:00:00.203]

Si tomo la declaración y los parámetros generados de los registros y los ejecuto a través de psql como se muestra a continuación, obtengo resultados correctos.

y quoteentit0_.action_time<='09:00:01.000'
y quoteentit0_.action_time>='09:00:00.203'

¿Dónde está mi problema? Gracias

ACTUALIZACIÓN
Después de depurar el código de Hibernate, encontré que el tipo LocalTime se asigna a la clase TimeTypeDescriptor de Hibernate, que utiliza la clase java.sql.Time, que no almacena milisegundos. Por lo tanto, el valor del parámetro real vinculado es 09:00:00. Estoy pensando en usar la clase LocalDateTime, que creo que se asignará a la clase TimestampTypeDescriptor de Hibernate, que utiliza la clase java.sql.Timestamp capaz de almacenar milisegundos. Sin embargo, esto no es óptimo ya que el campo de la base de datos es del tipo de tiempo y no sé qué hacer con la parte de la fecha.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Solución:

    El problema que está experimentando se debe al uso del tipo de campo LocalTime en su entidad Hibernate. El tipo de campo LocalTime se asigna a la clase TimeTypeDescriptor de Hibernate que utiliza la clase java.sql.Time que no almacena milisegundos. Como resultado, el valor del parámetro real vinculado es 09:00:00.

    Para resolver este problema, puede utilizar la clase LocalDateTime en lugar de la clase LocalTime en su entidad Hibernate. La clase LocalDateTime se puede asignar a la clase TimestampTypeDescriptor de Hibernate que utiliza java.sql.Timestamp capaz de almacenar milisegundos.

    Sin embargo, el uso de LocalDateTime para un campo que tiene un tipo de base de datos como tiempo es subóptimo ya que también almacena la parte de fecha que es innecesaria. En su lugar, puede considerar el uso de java.sql.Time para el campo de entidad y actualizar su código de aplicación para manejar las consultas de rango de tiempo de una manera que tenga en cuenta la porción de milisegundos del valor de tiempo.

    Otra solución posible es actualizar el tipo de campo de la base de datos de time a timestamp. Esto le permitirá utilizar LocalDateTime en su entidad Hibernate y también permitirá almacenar valores de milisegundos en la base de datos.

    En general, es necesario evaluar cuidadosamente los compromisos entre las diferentes soluciones y elegir la que mejor se adapte a los requisitos de su aplicación.

Comments are closed.