2012-04-09 14 views
10

Sto memorizzando il campo JodaTime DateTime nella colonna timestamptz utilizzando org.jadira.usertype:usertype.jodatime:1.9. Il server delle app ha +4 fuso orario. Server DB +9 fuso orario. new DateTime() restituisce ${currentTime+1hour}+9 dove +9 è fuso orario (il valore corretto è ${currentTime+5hours)+9).Ora joda DateTime memorizza in modo errato nella banca dati

Non ho trovato argomenti correlati. java.util.Date memorizza correttamente.

oggetto Dominio ha la seguente proprietà Mapping:

static mapping = { 
    dateCreated sqlType:'timestamptz' 
} 

Come posso conservare DateTime correttamente?

risposta

4

Ok. Ho impiegato 8 ore per risolvere il problema. Se si sta utilizzando il progetto usertype per mantenere JodaTime, è necessario impostare la proprietà databaseZone della classe PersistentDateTime uguale al fuso orario del server delle applicazioni corrente (non al database!).

Ma è meglio usare official hibernate support. Risolve il problema fuori dalla scatola perché utilizza java.utl.Date a persistere DateTime e java.util.Date correttamente persistito per default

+9

non si estende a Hibernate 4.0. :-(per il quale è necessario utilizzare usertype. –

0

Prova ad avviare JVM con -Duser.timezone = UTC a JAVA_OPTS in questo modo il tempo è in una zona e puoi quindi eseguire le tue operazioni su quello per convertirlo dove sei.

+0

Questo è un ottimo modo per andare - ma attenzione che non si può fare che se si dispone già di date memorizzate in un altro fuso orario nel DB. In altre parole, nessun problema per i nuovi progetti, ma sii molto, molto diffidente nel farlo per quelli con dati esistenti. Il supporto ufficiale di ibernazione – RedYeti

0

Fedor,

Ho ragione per supporre che si sta utilizzando Oracle TIMESTAMP CON colonna di fuso orario? Usertype non supporta ancora questo tipo (vale a dire con TIME ZONE) a causa della gestione con JDBC che differisce tra i database, anche se il progetto sarà felice di accettare le patch.

C'è qualche buona discussione WRT Oracle qui: http://puretech.paawak.com/2010/11/02/how-to-handle-oracle-timestamp-with-timezone-from-java/

+0

stiamo usando PostgreSQL timestamptz –

0

avevo risolto questo problema con la creazione di altri PersistentDateTime estende AbstractVersionableUserType.

import java.sql.Timestamp; 

import org.hibernate.SessionFactory; 
import org.hibernate.usertype.ParameterizedType; 
import org.jadira.usertype.dateandtime.joda.columnmapper.TimestampColumnDateTimeMapper; 
import org.jadira.usertype.spi.shared.AbstractVersionableUserType; 
import org.jadira.usertype.spi.shared.IntegratorConfiguredType; 
import org.joda.time.DateTime; 

public class PersistentDateTime extends AbstractVersionableUserType<DateTime, Timestamp, TimestampColumnDateTimeMapper> implements ParameterizedType, IntegratorConfiguredType { 

@Override 
public int compare(Object o1, Object o2) { 
    return ((DateTime) o1).compareTo((DateTime) o2); 
} 

@Override 
public void applyConfiguration(SessionFactory sessionFactory) { 

    super.applyConfiguration(sessionFactory); 

    TimestampColumnDateTimeMapper columnMapper = (TimestampColumnDateTimeMapper) getColumnMapper(); 
    columnMapper.setDatabaseZone(null); 
    columnMapper.setJavaZone(null); 
} 
} 
8

Ho avuto lo stesso problema. La specifica delle zone app e db in config ha risolto il problema.

  <prop key="jadira.usertype.autoRegisterUserTypes">true</prop> 
      <prop key="jadira.usertype.databaseZone">America/Los_Angeles</prop> 
      <prop key="jadira.usertype.javaZone">America/Los_Angeles</prop> 
+1

Questo funziona per Hibernate 4+ – Sudarshan

+1

Che file fa? – dgrant

9

Basta impostare le proprietà JPA:

<property name="jadira.usertype.autoRegisterUserTypes" 
      value="true"/> 
<property name="jadira.usertype.databaseZone" 
      value="jvm"/> 
<property name="jadira.usertype.javaZone" 
      value="jvm"/> 
+1

Che file fa questo? – dgrant

+0

@dgrant nel tuo file persistence.xml – Hamish

+0

C'è un modo per farlo senza un file XML? Il mio progetto sta usando pure annotazioni per la configurazione fino ad ora ... – Jules