Persisting attribute using "new" Java time Instant in MySQL


Page bloom
 
Edited

Traditionally we have used the java.util.Date class for storing time instants in UTC time - in all existing tables DN has created a 'TIMESTAMP' type field in MySQL - which works fine.

Recently we added our first attribute of type java.time.Instant (getting all jiggy with the "new" Java time library - better late than never!) and the DN docs say that the default mapping is a TIMESTAMP (via the convention that the bold type is the default):

https://www.datanucleus.org/products/accessplatform/jdo/mapping.html#_temporal_types_java_util_java_sql_java_time_jodatime

Java Type:  java.time.Instant
Comments:     Persisted as TIMESTAMP, String, Long, or DATETIME.

However, the Instant attribute has been mapped to a DATETIME instead of TIMESTAMP.

We have not added any specific customizations to the XML metadata so would assume that it would have mapped to the default TIMESTAMP.

Any idea what me going on? Have I misunderstood the docs? Do we need to explicitly set the MySQL type to TIMESTAMP somehow?


Page bloom
 

I tried adding an explicit JDBC type via:

        <field name="created">
                <column jdbc-type="TIMESTAMP" />
        </field>

but DN still creates a DATETIME column instead of a TIMESTAMP column.

I don't know why ...


Andy
 

If you look at what the MySQL JDBC driver provides to DataNucleus, you see that it supports DATETIME and TIMESTAMP as the SQL TYPE when the JDBC TYPE is TIMESTAMP.
https://github.com/datanucleus/datanucleus-rdbms/blob/master/docs/mysql-5.7.27-jdbc-8.0.28.txt

so setting the JDBC type to TIMESTAMP will simply result in the default SQL type for that JDBC type ... which is ... DATETIME. Run SchemaTool in "dbinfo" mode and you can see all you need to know


Page bloom
 
Edited

That was enlightening: I hadn't appreciated the two levels of types: JDBC types and MySQL types and that the mappings between them are not a simple one-to-one. Given that the type names are identical I assumed that TIMESTAMP (JDBC) would be mapped to TIMESTAMP (in MySQL)  - silly me ;)

I got specific with the sql-type and now it's working:

        <field name="created">
                <column jdbc-type="TIMESTAMP" sql-type="TIMESTAMP"/>
        </field>