HHH-8401 : Support fractional seconds on MySQL 5.7

(cherry picked from commit fe94cda1d1)
This commit is contained in:
Gail Badner 2014-12-16 21:05:01 -08:00
parent c068b6f70c
commit fa8383a22e
7 changed files with 819 additions and 0 deletions

View File

@ -0,0 +1,80 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2014, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.dialect;
import java.sql.Types;
import org.hibernate.dialect.function.SQLFunction;
import org.hibernate.dialect.function.StaticPrecisionFspTimestampFunction;
/**
* @author Gail Badner
*/
public class MySQL57InnoDBDialect extends MySQL5InnoDBDialect {
public MySQL57InnoDBDialect() {
super();
// For details about MySQL 5.7 support for fractional seconds
// precision (fsp): http://dev.mysql.com/doc/refman/5.7/en/fractional-seconds.html
// Regarding datetime(fsp), "The fsp value, if given, must be
// in the range 0 to 6. A value of 0 signifies that there is
// no fractional part. If omitted, the default precision is 0.
// (This differs from the standard SQL default of 6, for
// compatibility with previous MySQL versions.)".
// The following is defined because Hibernate currently expects
// the SQL 1992 default of 6 (which is inconsistent with the MySQL
// default).
registerColumnType( Types.TIMESTAMP, "datetime(6)" );
// MySQL also supports fractional seconds precision for time values
// (time(fsp)). According to SQL 1992, the default for <time precision>
// is 0. The MySQL default is time(0), there's no need to override
// the setting for Types.TIME columns.
// For details about MySQL support for timestamp functions, see:
// http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html
// The following are synonyms for now(fsp), where fsp defaults to 0 on MySQL 5.7:
// current_timestamp([fsp]), localtime(fsp), localtimestamp(fsp).
// Register the same StaticPrecisionFspTimestampFunction for all 4 functions.
final SQLFunction currentTimestampFunction = new StaticPrecisionFspTimestampFunction("now", 6 );
registerFunction( "now", currentTimestampFunction );
registerFunction( "current_timestamp", currentTimestampFunction );
registerFunction( "localtime", currentTimestampFunction );
registerFunction( "localtimestamp", currentTimestampFunction );
// sysdate is different from now():
// "SYSDATE() returns the time at which it executes. This differs
// from the behavior for NOW(), which returns a constant time that
// indicates the time at which the statement began to execute.
// (Within a stored function or trigger, NOW() returns the time at
// which the function or triggering statement began to execute.)
registerFunction( "sysdate", new StaticPrecisionFspTimestampFunction( "sysdate", 6 ) );
// from_unixtime(), timestamp() are functions that return TIMESTAMP that do not support a
// fractional seconds precision argument (so there's no need to override them here):
}
}

View File

@ -85,4 +85,8 @@ public class NoArgSQLFunction implements SQLFunction {
} }
return hasParenthesesIfNoArguments ? name + "()" : name; return hasParenthesesIfNoArguments ? name + "()" : name;
} }
protected String getName() {
return name;
}
} }

View File

@ -0,0 +1,79 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2014, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.dialect.function;
import java.util.List;
import org.hibernate.QueryException;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.Type;
/**
* A function that returns a {@link org.hibernate.type.StandardBasicTypes#TIMESTAMP}
* with static fractional seconds precision (fsp).
*
* @author Gail Badner
*/
public class StaticPrecisionFspTimestampFunction extends NoArgSQLFunction {
private final String renderedString;
/**
* Constructs a {@link org.hibernate.type.StandardBasicTypes#TIMESTAMP} function using the
* default fractional second precision as defined by the database.
*
* @param name The function name
* @param hasParenthesesIfNoArguments Does the function call need parenthesis if there are no arguments?
*/
public StaticPrecisionFspTimestampFunction(String name, boolean hasParenthesesIfNoArguments) {
super( name, StandardBasicTypes.TIMESTAMP, hasParenthesesIfNoArguments );
renderedString = null;
}
/**
* Constructs a {@link org.hibernate.type.StandardBasicTypes#TIMESTAMP} function using
* the specified fractional seconds precision.
* @param name The function name
* @param fsp The explicit fractional seconds precision to render
*
* @throws java.lang.IllegalArgumentException if {@code fsp} < 0.
*/
public StaticPrecisionFspTimestampFunction(String name, int fsp) {
super( name, StandardBasicTypes.TIMESTAMP);
if ( fsp < 0 ) {
throw new IllegalArgumentException( "fsp must be >= 0" );
}
renderedString = name + '(' + fsp + ')';
}
@Override
public String render(Type argumentType, List args, SessionFactoryImplementor factory) throws QueryException {
if ( args.size() > 0 ) {
throw new QueryException( "function takes no arguments: " + getName() );
}
return renderedString == null ?
super.render( argumentType, args, factory ) :
renderedString;
}
}

View File

@ -0,0 +1,102 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2014, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.test.temporal;
import java.sql.Timestamp;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import org.junit.Test;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.dialect.MySQL57InnoDBDialect;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/**
* @author Gail Badner.
*/
@TestForIssue( jiraKey = "HHH-8401")
@RequiresDialect( MySQL57InnoDBDialect.class )
public class MySQL57TimestampFspFunctionTest extends BaseCoreFunctionalTestCase {
@Test
public void testTimeStampFunctions() {
// add an entity just so it can be queried.
Session s=openSession();
Transaction tx = s.beginTransaction();
s.persist( new Entity() );
tx.commit();
s.close();
s = openSession();
tx = s.beginTransaction();
// current_timestamp(), localtime(), and localtimestamp() are synonyms for now(),
// which returns the time at which the statement began to execute.
// the returned values for now(), current_timestamp(), localtime(), and
// localtimestamp() should be the same.
// sysdate() is the time at which the function itself is executed, so the
// value returned for sysdate() should be different.
Query q=s.createQuery(
"select now(), current_timestamp(), localtime(), localtimestamp(), sysdate() from MySQL57TimestampFspFunctionTest$Entity"
);
Object[] oArray = (Object[]) q.uniqueResult();
final Timestamp now = (Timestamp) oArray[0];
assertEquals( now, oArray[1] );
assertEquals( now, oArray[2] );
assertEquals( now, oArray[3] );
final Timestamp sysdate = (Timestamp) oArray[4];
assertTrue( now.compareTo( sysdate ) < 0 );
// all should have nanos > 0
assertTrue( now.getNanos() > 0 );
assertTrue( sysdate.getNanos() > 0 );
tx.commit();
s.close();
}
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class[] { Entity.class };
}
// If MySQL supported something like Oracle's "dual", then this entity wouldn't be needed.
@javax.persistence.Entity
@Table(name = "DummyEntity")
public static class Entity {
@GeneratedValue
@Id
private long id;
}
}

View File

@ -0,0 +1,225 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2014, Red Hat, Inc. and/or its affiliates or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat, Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.test.temporal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.junit.Test;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.annotations.ColumnDefault;
import org.hibernate.annotations.Generated;
import org.hibernate.annotations.GenerationTime;
import org.hibernate.dialect.MySQL57InnoDBDialect;
import org.hibernate.dialect.MySQLDialect;
import org.hibernate.dialect.SybaseDialect;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.SkipForDialect;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import static junit.framework.Assert.assertNotNull;
import static org.junit.Assert.assertEquals;
/**
* @author Gail Badner
*/
@RequiresDialect(value = MySQL57InnoDBDialect.class)
@TestForIssue( jiraKey = "HHH-8401")
public class MySQL57TimestampPropertyTest extends BaseCoreFunctionalTestCase {
private final DateFormat timestampFormat = new SimpleDateFormat("HH:mm:ss.SSS");
@Test
public void testTime() {
final Entity eOrig = new Entity();
eOrig.ts = new Date();
Session s = openSession();
s.getTransaction().begin();
s.persist( eOrig );
s.getTransaction().commit();
s.close();
s = openSession();
s.getTransaction().begin();
final Entity eGotten = (Entity) s.get( Entity.class, eOrig.id );
final String tsOrigFormatted = timestampFormat.format( eOrig.ts );
final String tsGottenFormatted = timestampFormat.format( eGotten.ts );
assertEquals( tsOrigFormatted , tsGottenFormatted );
s.getTransaction().commit();
s.close();
s = openSession();
s.getTransaction().begin();
final Query queryWithParameter = s.createQuery( "from MySQL57TimestampPropertyTest$Entity where ts=?" ).setParameter( 0, eOrig.ts );
final Entity eQueriedWithParameter = (Entity) queryWithParameter.uniqueResult();
assertNotNull( eQueriedWithParameter );
s.getTransaction().commit();
s.close();
s = openSession();
s.getTransaction().begin();
final Query queryWithTimestamp = s.createQuery( "from MySQL57TimestampPropertyTest$Entity where ts=?" ).setTimestamp( 0, eOrig.ts );
final Entity eQueriedWithTimestamp = (Entity) queryWithTimestamp.uniqueResult();
assertNotNull( eQueriedWithTimestamp );
s.getTransaction().commit();
s.close();
s = openSession();
s.getTransaction().begin();
s.delete( eQueriedWithTimestamp );
s.getTransaction().commit();
s.close();
}
@Test
public void testTimeGeneratedByColumnDefault() {
final Entity eOrig = new Entity();
Session s = openSession();
s.getTransaction().begin();
s.persist( eOrig );
s.getTransaction().commit();
s.close();
assertNotNull( eOrig.tsColumnDefault );
s = openSession();
s.getTransaction().begin();
final Entity eGotten = (Entity) s.get( Entity.class, eOrig.id );
final String tsColumnDefaultOrigFormatted = timestampFormat.format( eOrig.tsColumnDefault );
final String tsColumnDefaultGottenFormatted = timestampFormat.format( eGotten.tsColumnDefault );
assertEquals( tsColumnDefaultOrigFormatted , tsColumnDefaultGottenFormatted );
s.getTransaction().commit();
s.close();
s = openSession();
s.getTransaction().begin();
final Query queryWithParameter =
s.createQuery( "from MySQL57TimestampPropertyTest$Entity where tsColumnDefault=?" )
.setParameter( 0, eOrig.tsColumnDefault );
final Entity eQueriedWithParameter = (Entity) queryWithParameter.uniqueResult();
assertNotNull( eQueriedWithParameter );
s.getTransaction().commit();
s.close();
s = openSession();
s.getTransaction().begin();
final Query queryWithTimestamp =
s.createQuery( "from MySQL57TimestampPropertyTest$Entity where tsColumnDefault=?" )
.setTimestamp( 0, eOrig.tsColumnDefault );
final Entity eQueriedWithTimestamp = (Entity) queryWithTimestamp.uniqueResult();
assertNotNull( eQueriedWithTimestamp );
s.getTransaction().commit();
s.close();
s = openSession();
s.getTransaction().begin();
s.delete( eQueriedWithTimestamp );
s.getTransaction().commit();
s.close();
}
@Test
public void testTimeGeneratedByColumnDefinition() {
final Entity eOrig = new Entity();
Session s = openSession();
s.getTransaction().begin();
s.persist( eOrig );
s.getTransaction().commit();
s.close();
assertNotNull( eOrig.tsColumnDefinition );
s = openSession();
s.getTransaction().begin();
final Entity eGotten = (Entity) s.get( Entity.class, eOrig.id );
final String tsColumnDefinitionOrigFormatted = timestampFormat.format( eOrig.tsColumnDefinition );
final String tsColumnDefinitionGottenFormatted = timestampFormat.format( eGotten.tsColumnDefinition );
assertEquals( tsColumnDefinitionOrigFormatted , tsColumnDefinitionGottenFormatted );
s.getTransaction().commit();
s.close();
s = openSession();
s.getTransaction().begin();
final Query queryWithParameter =
s.createQuery( "from MySQL57TimestampPropertyTest$Entity where tsColumnDefinition=?" )
.setParameter( 0, eOrig.tsColumnDefinition );
final Entity eQueriedWithParameter = (Entity) queryWithParameter.uniqueResult();
assertNotNull( eQueriedWithParameter );
s.getTransaction().commit();
s.close();
s = openSession();
s.getTransaction().begin();
final Query queryWithTimestamp =
s.createQuery( "from MySQL57TimestampPropertyTest$Entity where tsColumnDefinition=?" )
.setTimestamp( 0, eOrig.tsColumnDefinition );
final Entity eQueriedWithTimestamp = (Entity) queryWithTimestamp.uniqueResult();
assertNotNull( eQueriedWithTimestamp );
s.getTransaction().commit();
s.close();
s = openSession();
s.getTransaction().begin();
s.delete( eQueriedWithTimestamp );
s.getTransaction().commit();
s.close();
}
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class[] { Entity.class };
}
@javax.persistence.Entity
public static class Entity {
@GeneratedValue
@Id
private long id;
@Temporal( value = TemporalType.TIMESTAMP)
private Date ts;
@Temporal( value = TemporalType.TIMESTAMP )
@Generated( value = GenerationTime.INSERT )
@ColumnDefault( value = "CURRENT_TIMESTAMP(6)" )
private Date tsColumnDefault;
@Temporal( value = TemporalType.TIMESTAMP )
@Generated( value = GenerationTime.INSERT )
@Column( columnDefinition = "datetime(6) default NOW(6)" )
private Date tsColumnDefinition;
}
}

View File

@ -0,0 +1,102 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2014, Red Hat, Inc. and/or its affiliates or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat, Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.test.temporal;
import java.sql.Time;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.junit.Test;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
/**
* @author Gail Badner
*/
public class TimePropertyTest extends BaseCoreFunctionalTestCase {
private final DateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
@Test
public void testTimeAsDate() {
final Entity eOrig = new Entity();
eOrig.tAsDate = new Time( new Date().getTime() );
Session s = openSession();
s.getTransaction().begin();
s.persist( eOrig );
s.getTransaction().commit();
s.close();
s = openSession();
s.getTransaction().begin();
final Entity eGotten = (Entity) s.get( Entity.class, eOrig.id );
// Some databases retain the milliseconds when being inserted and some don't;
final String tAsDateOrigFormatted = timeFormat.format( eOrig.tAsDate );
final String tAsDateGottenFormatted = timeFormat.format( eGotten.tAsDate );
assertEquals( tAsDateOrigFormatted, tAsDateGottenFormatted );
s.getTransaction().commit();
s.close();
s = openSession();
s.getTransaction().begin();
final Query query = s.createQuery( "from TimePropertyTest$Entity where tAsDate=?" ).setTime( 0, eOrig.tAsDate );
final Entity eQueried = (Entity) query.uniqueResult();
assertNotNull( eQueried );
s.getTransaction().commit();
s.close();
s = openSession();
s.getTransaction().begin();
s.delete( eQueried );
s.getTransaction().commit();
s.close();
}
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class[] { Entity.class };
}
@javax.persistence.Entity
public static class Entity {
@GeneratedValue
@Id
private long id;
@Temporal( value = TemporalType.TIME )
private java.util.Date tAsDate;
}
}

View File

@ -0,0 +1,227 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2014, Red Hat, Inc. and/or its affiliates or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat, Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.test.temporal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.junit.Test;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.annotations.ColumnDefault;
import org.hibernate.annotations.Generated;
import org.hibernate.annotations.GenerationTime;
import org.hibernate.dialect.MySQLDialect;
import org.hibernate.dialect.SybaseDialect;
import org.hibernate.testing.SkipForDialect;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import static junit.framework.Assert.assertNotNull;
import static org.junit.Assert.assertEquals;
/**
* Tests that persisted timestamp properties have the expected format to milliseconds
* and tests that entities can be queried by timestamp value.
*
* See Mysql57TimestampFspTest for tests using MySQL 5.7. MySQL 5.7 is tested separately
* because it requires CURRENT_TIMESTAMP(6) or NOW(6) as a default.
*
* @author Gail Badner
*/
@SkipForDialect( value={SybaseDialect.class, MySQLDialect.class}, comment="CURRENT_TIMESTAMP not supported as default value in Sybase or MySQL" )
public class TimestampPropertyTest extends BaseCoreFunctionalTestCase {
private final DateFormat timestampFormat = new SimpleDateFormat("HH:mm:ss.SSS");
@Test
public void testTime() {
final Entity eOrig = new Entity();
eOrig.ts = new Date();
Session s = openSession();
s.getTransaction().begin();
s.persist( eOrig );
s.getTransaction().commit();
s.close();
s = openSession();
s.getTransaction().begin();
final Entity eGotten = (Entity) s.get( Entity.class, eOrig.id );
final String tsOrigFormatted = timestampFormat.format( eOrig.ts );
final String tsGottenFormatted = timestampFormat.format( eGotten.ts );
assertEquals( tsOrigFormatted , tsGottenFormatted );
s.getTransaction().commit();
s.close();
s = openSession();
s.getTransaction().begin();
final Query queryWithParameter = s.createQuery( "from TimestampPropertyTest$Entity where ts=?" ).setParameter( 0, eOrig.ts );
final Entity eQueriedWithParameter = (Entity) queryWithParameter.uniqueResult();
assertNotNull( eQueriedWithParameter );
s.getTransaction().commit();
s.close();
s = openSession();
s.getTransaction().begin();
final Query queryWithTimestamp = s.createQuery( "from TimestampPropertyTest$Entity where ts=?" ).setTimestamp( 0, eOrig.ts );
final Entity eQueriedWithTimestamp = (Entity) queryWithTimestamp.uniqueResult();
assertNotNull( eQueriedWithTimestamp );
s.getTransaction().commit();
s.close();
s = openSession();
s.getTransaction().begin();
s.delete( eQueriedWithTimestamp );
s.getTransaction().commit();
s.close();
}
@Test
public void testTimeGeneratedByColumnDefault() {
final Entity eOrig = new Entity();
Session s = openSession();
s.getTransaction().begin();
s.persist( eOrig );
s.getTransaction().commit();
s.close();
assertNotNull( eOrig.tsColumnDefault );
s = openSession();
s.getTransaction().begin();
final Entity eGotten = (Entity) s.get( Entity.class, eOrig.id );
final String tsColumnDefaultOrigFormatted = timestampFormat.format( eOrig.tsColumnDefault );
final String tsColumnDefaultGottenFormatted = timestampFormat.format( eGotten.tsColumnDefault );
assertEquals( tsColumnDefaultOrigFormatted , tsColumnDefaultGottenFormatted );
s.getTransaction().commit();
s.close();
s = openSession();
s.getTransaction().begin();
final Query queryWithParameter =
s.createQuery( "from TimestampPropertyTest$Entity where tsColumnDefault=?" )
.setParameter( 0, eOrig.tsColumnDefault );
final Entity eQueriedWithParameter = (Entity) queryWithParameter.uniqueResult();
assertNotNull( eQueriedWithParameter );
s.getTransaction().commit();
s.close();
s = openSession();
s.getTransaction().begin();
final Query queryWithTimestamp =
s.createQuery( "from TimestampPropertyTest$Entity where tsColumnDefault=?" )
.setTimestamp( 0, eOrig.tsColumnDefault );
final Entity eQueriedWithTimestamp = (Entity) queryWithTimestamp.uniqueResult();
assertNotNull( eQueriedWithTimestamp );
s.getTransaction().commit();
s.close();
s = openSession();
s.getTransaction().begin();
s.delete( eQueriedWithTimestamp );
s.getTransaction().commit();
s.close();
}
@Test
public void testTimeGeneratedByColumnDefinition() {
final Entity eOrig = new Entity();
Session s = openSession();
s.getTransaction().begin();
s.persist( eOrig );
s.getTransaction().commit();
s.close();
assertNotNull( eOrig.tsColumnDefinition );
s = openSession();
s.getTransaction().begin();
final Entity eGotten = (Entity) s.get( Entity.class, eOrig.id );
final String tsColumnDefinitionOrigFormatted = timestampFormat.format( eOrig.tsColumnDefinition );
final String tsColumnDefinitionGottenFormatted = timestampFormat.format( eGotten.tsColumnDefinition );
assertEquals( tsColumnDefinitionOrigFormatted , tsColumnDefinitionGottenFormatted );
s.getTransaction().commit();
s.close();
s = openSession();
s.getTransaction().begin();
final Query queryWithParameter =
s.createQuery( "from TimestampPropertyTest$Entity where tsColumnDefinition=?" )
.setParameter( 0, eOrig.tsColumnDefinition );
final Entity eQueriedWithParameter = (Entity) queryWithParameter.uniqueResult();
assertNotNull( eQueriedWithParameter );
s.getTransaction().commit();
s.close();
s = openSession();
s.getTransaction().begin();
final Query queryWithTimestamp =
s.createQuery( "from TimestampPropertyTest$Entity where tsColumnDefinition=?" )
.setTimestamp( 0, eOrig.tsColumnDefinition );
final Entity eQueriedWithTimestamp = (Entity) queryWithTimestamp.uniqueResult();
assertNotNull( eQueriedWithTimestamp );
s.getTransaction().commit();
s.close();
s = openSession();
s.getTransaction().begin();
s.delete( eQueriedWithTimestamp );
s.getTransaction().commit();
s.close();
}
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class[] { Entity.class };
}
@javax.persistence.Entity
public static class Entity {
@GeneratedValue
@Id
private long id;
@Temporal( value = TemporalType.TIMESTAMP)
private Date ts;
@Temporal( value = TemporalType.TIMESTAMP )
@Generated( value = GenerationTime.INSERT )
@ColumnDefault( value = "CURRENT_TIMESTAMP" )
private Date tsColumnDefault;
@Temporal( value = TemporalType.TIMESTAMP )
@Generated( value = GenerationTime.INSERT )
@Column( columnDefinition = "datetime(6) default NOW(6)" )
private Date tsColumnDefinition;
}
}