Joda time DateTime incorrectly stores in database
Asked Answered
M

7

11

I'm storing JodaTime DateTime field to timestamptz column by using org.jadira.usertype:usertype.jodatime:1.9. App server has +4 time zone. DB server +9 time zone. new DateTime() results in ${currentTime+1hour}+9 where +9 is time zone (correct value is ${currentTime+5hours)+9).

I haven't found any related topics. java.util.Date stores correctly.

Domain object has the following mapping property:

static mapping = {
    dateCreated sqlType:'timestamptz'
}

How can I store DateTime correctly?

Moskow answered 9/4, 2012 at 15:16 Comment(0)
M
6

Ok. I have spend 8 hours to solve the problem. If your are using usertype project to persist JodaTime, you have to set databaseZone property of PersistentDateTime class equals to current application server timezone (not database!).

But it's better to use official hibernate support. It solves the problem out of the box because it uses java.utl.Date to persist DateTime and java.util.Date correctly persisted by default

Moskow answered 12/4, 2012 at 7:43 Comment(1)
official hibernate support does not extend to Hibernate 4.0. :-( for which you need to use usertype.Candidacandidacy
B
10

Just set JPA properties:

<property name="jadira.usertype.autoRegisterUserTypes"
          value="true"/>
<property name="jadira.usertype.databaseZone"
          value="jvm"/>
<property name="jadira.usertype.javaZone"
          value="jvm"/>
Breakneck answered 26/5, 2013 at 15:33 Comment(3)
What file does this go in?Entomb
@Entomb in your persistence.xml fileSight
Is there a way of doing this without an XML file? My project is using pure annotations for config so far...Heyer
M
8

I had the same issue. Specifying app and db zones in config solved the issue.

            <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>
Margo answered 13/3, 2013 at 22:48 Comment(1)
What file does this go in?Entomb
M
6

Ok. I have spend 8 hours to solve the problem. If your are using usertype project to persist JodaTime, you have to set databaseZone property of PersistentDateTime class equals to current application server timezone (not database!).

But it's better to use official hibernate support. It solves the problem out of the box because it uses java.utl.Date to persist DateTime and java.util.Date correctly persisted by default

Moskow answered 12/4, 2012 at 7:43 Comment(1)
official hibernate support does not extend to Hibernate 4.0. :-( for which you need to use usertype.Candidacandidacy
A
1

Try starting JVM with -Duser.timezone=UTC to JAVA_OPTS that way the time is in one zone and you can then do your operations on that to convert it to where ever you are.

Adrianneadriano answered 11/4, 2012 at 3:50 Comment(1)
That's a great way to go - but be warned that you can't do that if you already have dates stored in another time zone in the DB. In other words, no problem for new projects but be very, very wary of doing this for ones with existing data.Hyperplane
F
0

Fedor,

Am I right to assume you are using Oracle TIMESTAMP WITH TIME ZONE column? Usertype doesn't support this type yet (i.e. with TIME ZONE) due to the handling with JDBC differing between databases, although the project will be happy to accept patches.

There's some good discussion wrt Oracle here: http://puretech.paawak.com/2010/11/02/how-to-handle-oracle-timestamp-with-timezone-from-java/

Fourlegged answered 15/4, 2012 at 7:11 Comment(1)
we are using PostgreSQL timestamptzMoskow
N
0

I had resolved this problems by creating other PersistentDateTime extends 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);
}
}
Nightwear answered 23/1, 2013 at 9:35 Comment(0)
C
0

Just an update for Spring Boot users. I was able to do the following:

spring.jpa.properties.jadira.usertype:
  autoRegisterUserTypes: true
  databaseZone: jvm
  javaZone: jvm

I put this in my application.yaml file.

Cordie answered 24/1, 2020 at 17:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.