2012-01-23 20 views
62

¿Están felizmente casados?Hibernate 4 y joda-time

Estoy utilizando la última versión de hibernate (4) y la versión 1.3 de joda-time hibernate support, que también creo que es la última versión actual.

Todo parece estar funcionando OK (columnas de fecha creadas como se espera) cuando se utiliza anotaciones:

@Column 
@Type(type="org.joda.time.contrib.hibernate.PersistentLocalDate") 
private LocalDate myDate; 

son sus problemas conocidos con el uso de estas versiones juntos?

actualización Pues resulta que las columnas se crean, pero incapaz de llenar con los datos:

procesamiento Handler fallado; la excepción jerarquizada es java.lang.AbstractMethodError: org.joda.time.contrib.hibernate.PersistentLocalDateTime.nullSafeSet

Son incompatibles, y que debería usar usertype. Ver la respuesta a continuación.

+0

Usted acaba de decirnos que * sí * trabajaron juntos, ¿no? – skaffman

+0

@skaffman No he probado nada más que la creación de columnas ... tenía entendido que las versiones anteriores (de joda-time lib) tenían que recompilarse contra la versión más reciente de hibernate. Esto sonó una alarma, de ahí la pregunta ... – NimChimpsky

+0

No están felizmente casados, Hibernate está teniendo otras relaciones ... y joda ...:/... Ella está herida – nobalG

Respuesta

96

Una escasez clara de documentación, significa que podría ser útil para mí anotar los pasos necesarios para la integración. Asegúrese de que sus bibliotecas estén actualizadas.

Necesitará: [suponiendo que ya tiene hibernate4]

La última versión de joda en tiempo

<dependency> 
    <groupId>joda-time</groupId> 
    <artifactId>joda-time</artifactId> 
    <version>2.0</version> 
</dependency> 

y lib usertype

<dependency> 
    <groupId>org.jadira.usertype</groupId> 
    <artifactId>usertype.core</artifactId> 
    <version>3.0.0.CR1</version> 
</dependency> 

continuación, utilizar el siguiente en clases de entidad (no tiene que ser LocalDateTime, podría ser cualquiera de las clases persistentes disponibles):

import org.joda.time.LocalDateTime; 

y para la definición de la columna:

@Column(name="updated", nullable = false) 
@Type(type="org.jadira.usertype.dateandtime.joda.PersistentLocalDateTime") 
private LocalDateTime updated; 
+1

¿Cómo sabemos a qué tipo se asigna en nuestra base de datos de elección? – benstpierre

+0

@Benju eche un vistazo a la tabla de la base de datos después de su creación ... – NimChimpsky

+0

Correcto, entonces use la generación automática de tablas y observe la salida? – benstpierre

29

Voy a añadir esto como una respuesta por separado, ya que es en mi opinión, la información importante para cualquiera que cambia a Hibernate 4, y en la necesidad de migrar a la utilización de tipos temporales persistentes de Jadira . Esta página está altamente clasificada en los resultados de búsqueda de Google para hibernate 4 y jodatime, así que la agregaré aquí. (Para una discusión separada de este tema, vea: Joda time DateTime incorrectly stores in database)

Si se encuentra en una zona horaria distinta a UTC, se necesita una configuración importante para obtener el mismo comportamiento que con una hibernación joda-time tipo de soporte. La forma en que los tipos temporales de jadira funcionan de manera predeterminada es mediante la conversión de todos los valores a la zona horaria UTC antes de continuar en la base de datos y la conversión a la zona horaria del sistema al cargar los valores de la base de datos.

Me quedé quemado después de la actualización, cuando tenía muchas marcas de tiempo con mi zona horaria exacta en la base de datos (UTC + 1 (+2 cuando en verano)). Cuando se cargó después de actualizar a Hibernate 4, 1 o 2 horas (dependiendo de si la marca de tiempo fue durante el horario de verano) se agregó al valor en la base de datos, lo que significa que todas las marcas de tiempo existentes se presentaron erróneamente. Además, los nuevos valores de marca de tiempo se almacenaron en la base de datos con la zona horaria UTC, lo que los llevó a aparecer correctamente en la aplicación, pero incorrecto en la base de datos.Con todo, un lío de zonas horarias y marcas de tiempo calientes.

Por lo tanto, con el fin de conseguir el mismo comportamiento que con Joda-tiempos de hibernación de soporte (la fecha y hora que se persistió siendo de la zona horaria del servidor en cuestión, y las marcas de tiempo en la base de datos es el mismo que lo que se está cargando en la aplicación), las siguientes propiedades se deben agregar a la configuración JPA/Hibernate (en mi caso, hibernate.properties):

jadira.usertype.autoRegisterUserTypes=true 
jadira.usertype.databaseZone=jvm 
jadira.usertype.javaZone=jvm 

Esto se asegurará de que las marcas de tiempo en la base de datos serán de la misma zona horaria como la de la aplicación, que a su vez será la zona horaria de la jvm (en la mayoría de los casos, el reloj del servidor de aplicaciones).

Además, por lo que entiendo, la autoRegisterUserTypes -property elimina la necesidad de que el @Type -annotation para una selección de tipos comunes, entre ellas las JodaTime tipos DateTime y LocalDate.

+2

Dado que ha resuelto su problema, y ​​no estaba directamente relacionado con esta pregunta, eliminaré mis comentarios y marcaré los suyos para su eliminación, por lo que mantendremos la sección de comentarios limpia y al grano. – Tobb

+0

Solo una pregunta: ¿por qué no almacenar cada marca de tiempo en hora UTC? ¿Qué pasa si el servidor se mueve a una zona horaria diferente? Imho sería mejor almacenar todas las marcas de tiempo en hora UTC y dejar que el cliente decida en qué zona horaria se encuentra. – displayname

+0

Como regla general, estaría de acuerdo. En mi caso, sin embargo, no había posibilidad de que el servidor se moviera a una zona horaria diferente. Además, el problema aquí es que el comportamiento predeterminado cambia, en mi caso, sin mi conocimiento. Entonces, cuando no sabe que esto sucede, no puede migrar sus datos y terminar con un conjunto de marcas de tiempo con diferentes zonas horarias, lo que por supuesto no es bueno. Pero, si tiene sentido para su proyecto, puede omitir la configuración proporcionada aquí y en su lugar migrar su base de datos. Una cosa que es negativa acerca de pasar todos los UTC es que los informes SQL se vuelven engañosos o incorrectos. – Tobb

Cuestiones relacionadas