Storing microseconds in a MySQL database

I have a Play Framework application with ebeans.To synchronise between the main system and an offline system I use an addDate field to identify unique records.

This works perfect while developing and initial testing (development with jdbc:h2:mem:play;MODE=MYSQL) and testing with a limited dataset.

But in production, with concurrent users I discovered that in the MySQL database milliseconds are not stored. I have the fields created as datetime(6), but a query like:

SELECT UNIX_TIMESTAMP(add_date) FROM `user` WHERE 1 

returns:

1499722493.000000
1499772800.000000
1499777225.000000
1499790922.000000
1499875868.000000
1499954855.000000
1499977124.000000
1499981148.000000
1499986822.000000

(ps. just selecting the add_date field in MySQL return 2015-12-17 16:15:50.000000, showing the precision is there)

So milliseconds are not stored. In Java I use the normal Date class, so they are in there (and so in the H2 men test database).

protected Date addDate;

How can I have the milliseconds stored in the Database with my current configuration without, hopefully, having to rewrite too much code?

[Edit:]

I am using MySQL on Debian: Ver 14.14 Distrib 5.6.35
sbt.version=0.13.11
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.5.16")
addSbtPlugin("com.typesafe.sbt" % "sbt-play-ebean" % "3.0.2")
mysql-connector-java % 5.1.43

2 answers

  • answered 2017-08-12 12:27 pagetronic

    In java you can not accurate to the microsecond (nanosecond) without taking a lot of system resources. Your date is inserted in milliseconds because java does it in milliseconds.

    If you want to use microseconds from SQL you must use the SQL NOW() on insertion.

  • answered 2017-08-13 04:11 Basil Bourque

    java.time

    The troublesome java.util.Date class is now supplanted by the java.time classes.

    The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).

    Capturing the current moment is limited to milliseconds in Java 8 but expanded to up to nanoseconds in Java 9 and later with a new implementation of Clock. To be clear, I'll repeat: Both Java 8 and Java 9 can store a value with nanoseconds, but only Java 9 and later can capture the current moment in finer than milliseconds resolution.

    Instant instant = Instant.now() ;  // Captures milliseconds in Java 8 but nanoseconds in Java 9+.
    

    Use a JDBC driver that complies with JDBC 4.2 or later, to work directly with the java.time types rather than the hacked java.sql types. Call the PreparedStatement::setObject and ResultSet::getObject methods.

    myPreparedStatement.setObject( … , instant ) ;
    

    …and…

    Instant instant = myResultSet.getObject( … , Instant.class ) ; // Transfers a value with nanoseconds if present.
    

    About java.time

    The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

    The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

    To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

    Where to obtain the java.time classes?

    The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.