HHH-15590 Test that JdbcLiteralFormatter works for all supported java types
This commit is contained in:
parent
b56d25c2b2
commit
f13230803d
|
@ -10,6 +10,7 @@ import java.sql.DatabaseMetaData;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
|
import java.time.temporal.ChronoField;
|
||||||
import java.time.temporal.TemporalAccessor;
|
import java.time.temporal.TemporalAccessor;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
@ -86,6 +87,7 @@ import static org.hibernate.query.sqm.TemporalUnit.DAY;
|
||||||
import static org.hibernate.query.sqm.TemporalUnit.NATIVE;
|
import static org.hibernate.query.sqm.TemporalUnit.NATIVE;
|
||||||
import static org.hibernate.type.SqlTypes.*;
|
import static org.hibernate.type.SqlTypes.*;
|
||||||
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsDate;
|
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsDate;
|
||||||
|
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsLocalTime;
|
||||||
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime;
|
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime;
|
||||||
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMicros;
|
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMicros;
|
||||||
|
|
||||||
|
@ -505,8 +507,14 @@ public class CockroachLegacyDialect extends Dialect {
|
||||||
appender.appendSql( '\'' );
|
appender.appendSql( '\'' );
|
||||||
break;
|
break;
|
||||||
case TIME:
|
case TIME:
|
||||||
appender.appendSql( "time '" );
|
if ( temporalAccessor.isSupported( ChronoField.OFFSET_SECONDS ) ) {
|
||||||
appendAsTime( appender, temporalAccessor, supportsTemporalLiteralOffset(), jdbcTimeZone );
|
appender.appendSql( "time with time zone '" );
|
||||||
|
appendAsTime( appender, temporalAccessor, true, jdbcTimeZone );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
appender.appendSql( "time '" );
|
||||||
|
appendAsLocalTime( appender, temporalAccessor );
|
||||||
|
}
|
||||||
appender.appendSql( '\'' );
|
appender.appendSql( '\'' );
|
||||||
break;
|
break;
|
||||||
case TIMESTAMP:
|
case TIMESTAMP:
|
||||||
|
@ -528,8 +536,8 @@ public class CockroachLegacyDialect extends Dialect {
|
||||||
appender.appendSql( '\'' );
|
appender.appendSql( '\'' );
|
||||||
break;
|
break;
|
||||||
case TIME:
|
case TIME:
|
||||||
appender.appendSql( "time '" );
|
appender.appendSql( "time with time zone '" );
|
||||||
appendAsTime( appender, date );
|
appendAsTime( appender, date, jdbcTimeZone );
|
||||||
appender.appendSql( '\'' );
|
appender.appendSql( '\'' );
|
||||||
break;
|
break;
|
||||||
case TIMESTAMP:
|
case TIMESTAMP:
|
||||||
|
@ -555,8 +563,8 @@ public class CockroachLegacyDialect extends Dialect {
|
||||||
appender.appendSql( '\'' );
|
appender.appendSql( '\'' );
|
||||||
break;
|
break;
|
||||||
case TIME:
|
case TIME:
|
||||||
appender.appendSql( "time '" );
|
appender.appendSql( "time with time zone '" );
|
||||||
appendAsTime( appender, calendar );
|
appendAsTime( appender, calendar, jdbcTimeZone );
|
||||||
appender.appendSql( '\'' );
|
appender.appendSql( '\'' );
|
||||||
break;
|
break;
|
||||||
case TIMESTAMP:
|
case TIMESTAMP:
|
||||||
|
|
|
@ -9,7 +9,12 @@ package org.hibernate.community.dialect;
|
||||||
import java.sql.CallableStatement;
|
import java.sql.CallableStatement;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
|
import java.time.temporal.ChronoField;
|
||||||
|
import java.time.temporal.TemporalAccessor;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
import org.hibernate.PessimisticLockException;
|
import org.hibernate.PessimisticLockException;
|
||||||
import org.hibernate.boot.model.TypeContributions;
|
import org.hibernate.boot.model.TypeContributions;
|
||||||
|
@ -96,6 +101,10 @@ import static org.hibernate.type.SqlTypes.TIMESTAMP_UTC;
|
||||||
import static org.hibernate.type.SqlTypes.UUID;
|
import static org.hibernate.type.SqlTypes.UUID;
|
||||||
import static org.hibernate.type.SqlTypes.VARBINARY;
|
import static org.hibernate.type.SqlTypes.VARBINARY;
|
||||||
import static org.hibernate.type.SqlTypes.VARCHAR;
|
import static org.hibernate.type.SqlTypes.VARCHAR;
|
||||||
|
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsDate;
|
||||||
|
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsLocalTime;
|
||||||
|
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime;
|
||||||
|
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMicros;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A legacy {@linkplain Dialect SQL dialect} for H2.
|
* A legacy {@linkplain Dialect SQL dialect} for H2.
|
||||||
|
@ -439,6 +448,105 @@ public class H2LegacyDialect extends Dialect {
|
||||||
return "datediff(?1,?2,?3)";
|
return "datediff(?1,?2,?3)";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void appendDateTimeLiteral(
|
||||||
|
SqlAppender appender,
|
||||||
|
TemporalAccessor temporalAccessor,
|
||||||
|
TemporalType precision,
|
||||||
|
TimeZone jdbcTimeZone) {
|
||||||
|
switch ( precision ) {
|
||||||
|
case DATE:
|
||||||
|
appender.appendSql( "date '" );
|
||||||
|
appendAsDate( appender, temporalAccessor );
|
||||||
|
appender.appendSql( '\'' );
|
||||||
|
break;
|
||||||
|
case TIME:
|
||||||
|
if ( temporalAccessor.isSupported( ChronoField.OFFSET_SECONDS ) && supportsTimeWithTimeZoneLiteral() ) {
|
||||||
|
appender.appendSql( "time with time zone '" );
|
||||||
|
appendAsTime( appender, temporalAccessor, supportsTemporalLiteralOffset(), jdbcTimeZone );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
appender.appendSql( "time '" );
|
||||||
|
appendAsLocalTime( appender, temporalAccessor );
|
||||||
|
}
|
||||||
|
appender.appendSql( '\'' );
|
||||||
|
break;
|
||||||
|
case TIMESTAMP:
|
||||||
|
appender.appendSql( "timestamp with time zone '" );
|
||||||
|
appendAsTimestampWithMicros( appender, temporalAccessor, supportsTemporalLiteralOffset(), jdbcTimeZone );
|
||||||
|
appender.appendSql( '\'' );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void appendDateTimeLiteral(SqlAppender appender, Date date, TemporalType precision, TimeZone jdbcTimeZone) {
|
||||||
|
switch ( precision ) {
|
||||||
|
case DATE:
|
||||||
|
appender.appendSql( "date '" );
|
||||||
|
appendAsDate( appender, date );
|
||||||
|
appender.appendSql( '\'' );
|
||||||
|
break;
|
||||||
|
case TIME:
|
||||||
|
if ( supportsTimeWithTimeZoneLiteral() ) {
|
||||||
|
appender.appendSql( "time with time zone '" );
|
||||||
|
appendAsTime( appender, date, jdbcTimeZone );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
appender.appendSql( "time '" );
|
||||||
|
appendAsLocalTime( appender, date );
|
||||||
|
}
|
||||||
|
appender.appendSql( '\'' );
|
||||||
|
break;
|
||||||
|
case TIMESTAMP:
|
||||||
|
appender.appendSql( "timestamp with time zone '" );
|
||||||
|
appendAsTimestampWithMicros( appender, date, jdbcTimeZone );
|
||||||
|
appender.appendSql( '\'' );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void appendDateTimeLiteral(
|
||||||
|
SqlAppender appender,
|
||||||
|
Calendar calendar,
|
||||||
|
TemporalType precision,
|
||||||
|
TimeZone jdbcTimeZone) {
|
||||||
|
switch ( precision ) {
|
||||||
|
case DATE:
|
||||||
|
appender.appendSql( "date '" );
|
||||||
|
appendAsDate( appender, calendar );
|
||||||
|
appender.appendSql( '\'' );
|
||||||
|
break;
|
||||||
|
case TIME:
|
||||||
|
if ( supportsTimeWithTimeZoneLiteral() ) {
|
||||||
|
appender.appendSql( "time with time zone '" );
|
||||||
|
appendAsTime( appender, calendar, jdbcTimeZone );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
appender.appendSql( "time '" );
|
||||||
|
appendAsLocalTime( appender, calendar );
|
||||||
|
}
|
||||||
|
appender.appendSql( '\'' );
|
||||||
|
break;
|
||||||
|
case TIMESTAMP:
|
||||||
|
appender.appendSql( "timestamp with time zone '" );
|
||||||
|
appendAsTimestampWithMicros( appender, calendar, jdbcTimeZone );
|
||||||
|
appender.appendSql( '\'' );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsTimeWithTimeZoneLiteral() {
|
||||||
|
return getVersion().isSameOrAfter( 1, 4, 200 );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsTemporalLiteralOffset() {
|
public boolean supportsTemporalLiteralOffset() {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -11,6 +11,7 @@ import java.sql.DatabaseMetaData;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
|
import java.time.temporal.ChronoField;
|
||||||
import java.time.temporal.TemporalAccessor;
|
import java.time.temporal.TemporalAccessor;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
@ -130,6 +131,7 @@ import static org.hibernate.type.SqlTypes.UUID;
|
||||||
import static org.hibernate.type.SqlTypes.VARBINARY;
|
import static org.hibernate.type.SqlTypes.VARBINARY;
|
||||||
import static org.hibernate.type.SqlTypes.VARCHAR;
|
import static org.hibernate.type.SqlTypes.VARCHAR;
|
||||||
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsDate;
|
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsDate;
|
||||||
|
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsLocalTime;
|
||||||
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime;
|
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime;
|
||||||
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMicros;
|
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMicros;
|
||||||
|
|
||||||
|
@ -1057,8 +1059,14 @@ public class PostgreSQLLegacyDialect extends Dialect {
|
||||||
appender.appendSql( '\'' );
|
appender.appendSql( '\'' );
|
||||||
break;
|
break;
|
||||||
case TIME:
|
case TIME:
|
||||||
appender.appendSql( "time '" );
|
if ( temporalAccessor.isSupported( ChronoField.OFFSET_SECONDS ) ) {
|
||||||
appendAsTime( appender, temporalAccessor, supportsTemporalLiteralOffset(), jdbcTimeZone );
|
appender.appendSql( "time with time zone '" );
|
||||||
|
appendAsTime( appender, temporalAccessor, true, jdbcTimeZone );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
appender.appendSql( "time '" );
|
||||||
|
appendAsLocalTime( appender, temporalAccessor );
|
||||||
|
}
|
||||||
appender.appendSql( '\'' );
|
appender.appendSql( '\'' );
|
||||||
break;
|
break;
|
||||||
case TIMESTAMP:
|
case TIMESTAMP:
|
||||||
|
@ -1080,8 +1088,8 @@ public class PostgreSQLLegacyDialect extends Dialect {
|
||||||
appender.appendSql( '\'' );
|
appender.appendSql( '\'' );
|
||||||
break;
|
break;
|
||||||
case TIME:
|
case TIME:
|
||||||
appender.appendSql( "time '" );
|
appender.appendSql( "time with time zone '" );
|
||||||
appendAsTime( appender, date );
|
appendAsTime( appender, date, jdbcTimeZone );
|
||||||
appender.appendSql( '\'' );
|
appender.appendSql( '\'' );
|
||||||
break;
|
break;
|
||||||
case TIMESTAMP:
|
case TIMESTAMP:
|
||||||
|
@ -1107,8 +1115,8 @@ public class PostgreSQLLegacyDialect extends Dialect {
|
||||||
appender.appendSql( '\'' );
|
appender.appendSql( '\'' );
|
||||||
break;
|
break;
|
||||||
case TIME:
|
case TIME:
|
||||||
appender.appendSql( "time '" );
|
appender.appendSql( "time with time zone '" );
|
||||||
appendAsTime( appender, calendar );
|
appendAsTime( appender, calendar, jdbcTimeZone );
|
||||||
appender.appendSql( '\'' );
|
appender.appendSql( '\'' );
|
||||||
break;
|
break;
|
||||||
case TIMESTAMP:
|
case TIMESTAMP:
|
||||||
|
|
|
@ -10,6 +10,7 @@ import java.sql.DatabaseMetaData;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
|
import java.time.temporal.ChronoField;
|
||||||
import java.time.temporal.TemporalAccessor;
|
import java.time.temporal.TemporalAccessor;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
@ -94,6 +95,7 @@ import static org.hibernate.type.SqlTypes.UUID;
|
||||||
import static org.hibernate.type.SqlTypes.VARBINARY;
|
import static org.hibernate.type.SqlTypes.VARBINARY;
|
||||||
import static org.hibernate.type.SqlTypes.VARCHAR;
|
import static org.hibernate.type.SqlTypes.VARCHAR;
|
||||||
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsDate;
|
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsDate;
|
||||||
|
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsLocalTime;
|
||||||
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime;
|
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime;
|
||||||
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMicros;
|
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMicros;
|
||||||
|
|
||||||
|
@ -509,8 +511,14 @@ public class CockroachDialect extends Dialect {
|
||||||
appender.appendSql( '\'' );
|
appender.appendSql( '\'' );
|
||||||
break;
|
break;
|
||||||
case TIME:
|
case TIME:
|
||||||
appender.appendSql( "time '" );
|
if ( temporalAccessor.isSupported( ChronoField.OFFSET_SECONDS ) ) {
|
||||||
appendAsTime( appender, temporalAccessor, supportsTemporalLiteralOffset(), jdbcTimeZone );
|
appender.appendSql( "time with time zone '" );
|
||||||
|
appendAsTime( appender, temporalAccessor, true, jdbcTimeZone );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
appender.appendSql( "time '" );
|
||||||
|
appendAsLocalTime( appender, temporalAccessor );
|
||||||
|
}
|
||||||
appender.appendSql( '\'' );
|
appender.appendSql( '\'' );
|
||||||
break;
|
break;
|
||||||
case TIMESTAMP:
|
case TIMESTAMP:
|
||||||
|
@ -532,8 +540,8 @@ public class CockroachDialect extends Dialect {
|
||||||
appender.appendSql( '\'' );
|
appender.appendSql( '\'' );
|
||||||
break;
|
break;
|
||||||
case TIME:
|
case TIME:
|
||||||
appender.appendSql( "time '" );
|
appender.appendSql( "time with time zone '" );
|
||||||
appendAsTime( appender, date );
|
appendAsTime( appender, date, jdbcTimeZone );
|
||||||
appender.appendSql( '\'' );
|
appender.appendSql( '\'' );
|
||||||
break;
|
break;
|
||||||
case TIMESTAMP:
|
case TIMESTAMP:
|
||||||
|
@ -559,8 +567,8 @@ public class CockroachDialect extends Dialect {
|
||||||
appender.appendSql( '\'' );
|
appender.appendSql( '\'' );
|
||||||
break;
|
break;
|
||||||
case TIME:
|
case TIME:
|
||||||
appender.appendSql( "time '" );
|
appender.appendSql( "time with time zone '" );
|
||||||
appendAsTime( appender, calendar );
|
appendAsTime( appender, calendar, jdbcTimeZone );
|
||||||
appender.appendSql( '\'' );
|
appender.appendSql( '\'' );
|
||||||
break;
|
break;
|
||||||
case TIMESTAMP:
|
case TIMESTAMP:
|
||||||
|
|
|
@ -35,6 +35,7 @@ import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
|
@ -4206,7 +4207,13 @@ public abstract class Dialect implements ConversionContext {
|
||||||
appender.appendSql( literal.getSeconds() );
|
appender.appendSql( literal.getSeconds() );
|
||||||
appender.appendSql( '.' );
|
appender.appendSql( '.' );
|
||||||
appender.appendSql( literal.getNano() );
|
appender.appendSql( literal.getNano() );
|
||||||
appender.appendSql( '\'' );
|
appender.appendSql( "' second" );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void appendUUIDLiteral(SqlAppender appender, UUID literal) {
|
||||||
|
appender.appendSql( "cast('" );
|
||||||
|
appender.appendSql( literal.toString() );
|
||||||
|
appender.appendSql( "' as uuid)" );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -9,7 +9,12 @@ package org.hibernate.dialect;
|
||||||
import java.sql.CallableStatement;
|
import java.sql.CallableStatement;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
|
import java.time.temporal.ChronoField;
|
||||||
|
import java.time.temporal.TemporalAccessor;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
import org.hibernate.PessimisticLockException;
|
import org.hibernate.PessimisticLockException;
|
||||||
import org.hibernate.boot.model.TypeContributions;
|
import org.hibernate.boot.model.TypeContributions;
|
||||||
|
@ -84,6 +89,10 @@ import static org.hibernate.type.SqlTypes.UUID;
|
||||||
import static org.hibernate.type.SqlTypes.VARBINARY;
|
import static org.hibernate.type.SqlTypes.VARBINARY;
|
||||||
import static org.hibernate.type.SqlTypes.VARCHAR;
|
import static org.hibernate.type.SqlTypes.VARCHAR;
|
||||||
import static org.hibernate.type.SqlTypes.TIMESTAMP_UTC;
|
import static org.hibernate.type.SqlTypes.TIMESTAMP_UTC;
|
||||||
|
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsDate;
|
||||||
|
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsLocalTime;
|
||||||
|
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime;
|
||||||
|
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMicros;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@linkplain Dialect SQL dialect} for H2.
|
* A {@linkplain Dialect SQL dialect} for H2.
|
||||||
|
@ -406,6 +415,105 @@ public class H2Dialect extends Dialect {
|
||||||
return "datediff(?1,?2,?3)";
|
return "datediff(?1,?2,?3)";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void appendDateTimeLiteral(
|
||||||
|
SqlAppender appender,
|
||||||
|
TemporalAccessor temporalAccessor,
|
||||||
|
TemporalType precision,
|
||||||
|
TimeZone jdbcTimeZone) {
|
||||||
|
switch ( precision ) {
|
||||||
|
case DATE:
|
||||||
|
appender.appendSql( "date '" );
|
||||||
|
appendAsDate( appender, temporalAccessor );
|
||||||
|
appender.appendSql( '\'' );
|
||||||
|
break;
|
||||||
|
case TIME:
|
||||||
|
if ( temporalAccessor.isSupported( ChronoField.OFFSET_SECONDS ) && supportsTimeWithTimeZoneLiteral() ) {
|
||||||
|
appender.appendSql( "time with time zone '" );
|
||||||
|
appendAsTime( appender, temporalAccessor, supportsTemporalLiteralOffset(), jdbcTimeZone );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
appender.appendSql( "time '" );
|
||||||
|
appendAsLocalTime( appender, temporalAccessor );
|
||||||
|
}
|
||||||
|
appender.appendSql( '\'' );
|
||||||
|
break;
|
||||||
|
case TIMESTAMP:
|
||||||
|
appender.appendSql( "timestamp with time zone '" );
|
||||||
|
appendAsTimestampWithMicros( appender, temporalAccessor, supportsTemporalLiteralOffset(), jdbcTimeZone );
|
||||||
|
appender.appendSql( '\'' );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void appendDateTimeLiteral(SqlAppender appender, Date date, TemporalType precision, TimeZone jdbcTimeZone) {
|
||||||
|
switch ( precision ) {
|
||||||
|
case DATE:
|
||||||
|
appender.appendSql( "date '" );
|
||||||
|
appendAsDate( appender, date );
|
||||||
|
appender.appendSql( '\'' );
|
||||||
|
break;
|
||||||
|
case TIME:
|
||||||
|
if ( supportsTimeWithTimeZoneLiteral() ) {
|
||||||
|
appender.appendSql( "time with time zone '" );
|
||||||
|
appendAsTime( appender, date, jdbcTimeZone );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
appender.appendSql( "time '" );
|
||||||
|
appendAsLocalTime( appender, date );
|
||||||
|
}
|
||||||
|
appender.appendSql( '\'' );
|
||||||
|
break;
|
||||||
|
case TIMESTAMP:
|
||||||
|
appender.appendSql( "timestamp with time zone '" );
|
||||||
|
appendAsTimestampWithMicros( appender, date, jdbcTimeZone );
|
||||||
|
appender.appendSql( '\'' );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void appendDateTimeLiteral(
|
||||||
|
SqlAppender appender,
|
||||||
|
Calendar calendar,
|
||||||
|
TemporalType precision,
|
||||||
|
TimeZone jdbcTimeZone) {
|
||||||
|
switch ( precision ) {
|
||||||
|
case DATE:
|
||||||
|
appender.appendSql( "date '" );
|
||||||
|
appendAsDate( appender, calendar );
|
||||||
|
appender.appendSql( '\'' );
|
||||||
|
break;
|
||||||
|
case TIME:
|
||||||
|
if ( supportsTimeWithTimeZoneLiteral() ) {
|
||||||
|
appender.appendSql( "time with time zone '" );
|
||||||
|
appendAsTime( appender, calendar, jdbcTimeZone );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
appender.appendSql( "time '" );
|
||||||
|
appendAsLocalTime( appender, calendar );
|
||||||
|
}
|
||||||
|
appender.appendSql( '\'' );
|
||||||
|
break;
|
||||||
|
case TIMESTAMP:
|
||||||
|
appender.appendSql( "timestamp with time zone '" );
|
||||||
|
appendAsTimestampWithMicros( appender, calendar, jdbcTimeZone );
|
||||||
|
appender.appendSql( '\'' );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsTimeWithTimeZoneLiteral() {
|
||||||
|
return getVersion().isSameOrAfter( 1, 4, 200 );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsTemporalLiteralOffset() {
|
public boolean supportsTemporalLiteralOffset() {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -11,6 +11,7 @@ import java.sql.DatabaseMetaData;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
|
import java.time.temporal.ChronoField;
|
||||||
import java.time.temporal.TemporalAccessor;
|
import java.time.temporal.TemporalAccessor;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
@ -113,6 +114,7 @@ import static org.hibernate.type.SqlTypes.UUID;
|
||||||
import static org.hibernate.type.SqlTypes.VARBINARY;
|
import static org.hibernate.type.SqlTypes.VARBINARY;
|
||||||
import static org.hibernate.type.SqlTypes.VARCHAR;
|
import static org.hibernate.type.SqlTypes.VARCHAR;
|
||||||
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsDate;
|
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsDate;
|
||||||
|
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsLocalTime;
|
||||||
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime;
|
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime;
|
||||||
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMicros;
|
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMicros;
|
||||||
|
|
||||||
|
@ -1028,8 +1030,14 @@ public class PostgreSQLDialect extends Dialect {
|
||||||
appender.appendSql( '\'' );
|
appender.appendSql( '\'' );
|
||||||
break;
|
break;
|
||||||
case TIME:
|
case TIME:
|
||||||
appender.appendSql( "time '" );
|
if ( temporalAccessor.isSupported( ChronoField.OFFSET_SECONDS ) ) {
|
||||||
appendAsTime( appender, temporalAccessor, supportsTemporalLiteralOffset(), jdbcTimeZone );
|
appender.appendSql( "time with time zone '" );
|
||||||
|
appendAsTime( appender, temporalAccessor, true, jdbcTimeZone );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
appender.appendSql( "time '" );
|
||||||
|
appendAsLocalTime( appender, temporalAccessor );
|
||||||
|
}
|
||||||
appender.appendSql( '\'' );
|
appender.appendSql( '\'' );
|
||||||
break;
|
break;
|
||||||
case TIMESTAMP:
|
case TIMESTAMP:
|
||||||
|
@ -1051,8 +1059,8 @@ public class PostgreSQLDialect extends Dialect {
|
||||||
appender.appendSql( '\'' );
|
appender.appendSql( '\'' );
|
||||||
break;
|
break;
|
||||||
case TIME:
|
case TIME:
|
||||||
appender.appendSql( "time '" );
|
appender.appendSql( "time with time zone '" );
|
||||||
appendAsTime( appender, date );
|
appendAsTime( appender, date, jdbcTimeZone );
|
||||||
appender.appendSql( '\'' );
|
appender.appendSql( '\'' );
|
||||||
break;
|
break;
|
||||||
case TIMESTAMP:
|
case TIMESTAMP:
|
||||||
|
@ -1078,8 +1086,8 @@ public class PostgreSQLDialect extends Dialect {
|
||||||
appender.appendSql( '\'' );
|
appender.appendSql( '\'' );
|
||||||
break;
|
break;
|
||||||
case TIME:
|
case TIME:
|
||||||
appender.appendSql( "time '" );
|
appender.appendSql( "time with time zone '" );
|
||||||
appendAsTime( appender, calendar );
|
appendAsTime( appender, calendar, jdbcTimeZone );
|
||||||
appender.appendSql( '\'' );
|
appender.appendSql( '\'' );
|
||||||
break;
|
break;
|
||||||
case TIMESTAMP:
|
case TIMESTAMP:
|
||||||
|
|
|
@ -68,6 +68,7 @@ import java.time.temporal.TemporalAccessor;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import jakarta.persistence.TemporalType;
|
import jakarta.persistence.TemporalType;
|
||||||
|
|
||||||
|
@ -785,6 +786,12 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
|
||||||
PrimitiveByteArrayJavaType.INSTANCE.appendString( appender, bytes );
|
PrimitiveByteArrayJavaType.INSTANCE.appendString( appender, bytes );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void appendUUIDLiteral(SqlAppender appender, java.util.UUID literal) {
|
||||||
|
appender.appendSql( "cast('" );
|
||||||
|
appender.appendSql( literal.toString() );
|
||||||
|
appender.appendSql( "' as uniqueidentifier)" );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void appendDateTimeLiteral(
|
public void appendDateTimeLiteral(
|
||||||
SqlAppender appender,
|
SqlAppender appender,
|
||||||
|
|
|
@ -19,7 +19,9 @@ import org.hibernate.type.descriptor.WrapperOptions;
|
||||||
import org.hibernate.type.descriptor.java.JavaType;
|
import org.hibernate.type.descriptor.java.JavaType;
|
||||||
import org.hibernate.type.descriptor.jdbc.BasicBinder;
|
import org.hibernate.type.descriptor.jdbc.BasicBinder;
|
||||||
import org.hibernate.type.descriptor.jdbc.BasicExtractor;
|
import org.hibernate.type.descriptor.jdbc.BasicExtractor;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.JdbcLiteralFormatter;
|
||||||
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.internal.JdbcLiteralFormatterUUIDData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specialized type mapping for {@link UUID} and the UUID SQL data type,
|
* Specialized type mapping for {@link UUID} and the UUID SQL data type,
|
||||||
|
@ -52,6 +54,11 @@ public class VarcharUUIDJdbcType implements JdbcType {
|
||||||
return UUID.class;
|
return UUID.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> JdbcLiteralFormatter<T> getJdbcLiteralFormatter(JavaType<T> javaType) {
|
||||||
|
return new JdbcLiteralFormatterUUIDData<>( javaType );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <X> ValueBinder<X> getBinder(JavaType<X> javaType) {
|
public <X> ValueBinder<X> getBinder(JavaType<X> javaType) {
|
||||||
return new BasicBinder<>( javaType, this ) {
|
return new BasicBinder<>( javaType, this ) {
|
||||||
|
|
|
@ -10,6 +10,7 @@ import java.io.IOException;
|
||||||
import java.io.InvalidObjectException;
|
import java.io.InvalidObjectException;
|
||||||
import java.io.ObjectInputStream;
|
import java.io.ObjectInputStream;
|
||||||
import java.io.ObjectOutputStream;
|
import java.io.ObjectOutputStream;
|
||||||
|
import java.io.Serializable;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -1068,9 +1069,21 @@ public class SessionFactoryImpl implements SessionFactoryImplementor {
|
||||||
clazz = bindValue.getClass();
|
clazz = bindValue.getClass();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
// Resolve superclass bindable type if necessary, as we don't register types for e.g. Inet4Address
|
||||||
Class<? extends T> c = (Class<? extends T>) clazz;
|
Class<?> c = clazz;
|
||||||
return resolveParameterBindType( c );
|
do {
|
||||||
|
BindableType<?> type = resolveParameterBindType( c );
|
||||||
|
if ( type != null ) {
|
||||||
|
//noinspection unchecked
|
||||||
|
return (BindableType<? extends T>) type;
|
||||||
|
}
|
||||||
|
c = c.getSuperclass();
|
||||||
|
} while ( c != Object.class );
|
||||||
|
if ( !clazz.isEnum() && Serializable.class.isAssignableFrom( clazz ) ) {
|
||||||
|
//noinspection unchecked
|
||||||
|
return (BindableType<? extends T>) resolveParameterBindType( Serializable.class );
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -10,6 +10,7 @@ import java.sql.Timestamp;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.time.format.DateTimeFormatterBuilder;
|
import java.time.format.DateTimeFormatterBuilder;
|
||||||
import java.time.temporal.ChronoField;
|
import java.time.temporal.ChronoField;
|
||||||
|
@ -35,23 +36,33 @@ public final class DateTimeUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String FORMAT_STRING_DATE = "yyyy-MM-dd";
|
public static final String FORMAT_STRING_DATE = "yyyy-MM-dd";
|
||||||
public static final String FORMAT_STRING_TIME_WITH_OFFSET = "HH:mm:ssxxx";
|
public static final String FORMAT_STRING_TIME_WITH_OFFSET = "HH:mm:ssXXX";
|
||||||
public static final String FORMAT_STRING_TIME = "HH:mm:ss";
|
public static final String FORMAT_STRING_TIME = "HH:mm:ss";
|
||||||
public static final String FORMAT_STRING_TIMESTAMP = "yyyy-MM-dd HH:mm:ss";
|
public static final String FORMAT_STRING_TIMESTAMP = "yyyy-MM-dd HH:mm:ss";
|
||||||
public static final String FORMAT_STRING_TIMESTAMP_WITH_MILLIS = FORMAT_STRING_TIMESTAMP + ".SSS";
|
public static final String FORMAT_STRING_TIMESTAMP_WITH_MILLIS = FORMAT_STRING_TIMESTAMP + ".SSS";
|
||||||
public static final String FORMAT_STRING_TIMESTAMP_WITH_MICROS = FORMAT_STRING_TIMESTAMP + ".SSSSSS";
|
public static final String FORMAT_STRING_TIMESTAMP_WITH_MICROS = FORMAT_STRING_TIMESTAMP + ".SSSSSS";
|
||||||
public static final String FORMAT_STRING_TIMESTAMP_WITH_MILLIS_AND_OFFSET = FORMAT_STRING_TIMESTAMP_WITH_MILLIS + "xxx";
|
public static final String FORMAT_STRING_TIMESTAMP_WITH_MILLIS_AND_OFFSET = FORMAT_STRING_TIMESTAMP_WITH_MILLIS + "XXX";
|
||||||
public static final String FORMAT_STRING_TIMESTAMP_WITH_MICROS_AND_OFFSET = FORMAT_STRING_TIMESTAMP_WITH_MICROS + "xxx";
|
public static final String FORMAT_STRING_TIMESTAMP_WITH_MICROS_AND_OFFSET = FORMAT_STRING_TIMESTAMP_WITH_MICROS + "XXX";
|
||||||
|
|
||||||
public static final DateTimeFormatter DATE_TIME_FORMATTER_DATE = DateTimeFormatter.ofPattern( FORMAT_STRING_DATE, Locale.ENGLISH );
|
public static final DateTimeFormatter DATE_TIME_FORMATTER_DATE = DateTimeFormatter.ofPattern( FORMAT_STRING_DATE, Locale.ENGLISH );
|
||||||
public static final DateTimeFormatter DATE_TIME_FORMATTER_TIME_WITH_OFFSET = DateTimeFormatter.ofPattern( FORMAT_STRING_TIME_WITH_OFFSET, Locale.ENGLISH );
|
public static final DateTimeFormatter DATE_TIME_FORMATTER_TIME_WITH_OFFSET = DateTimeFormatter.ofPattern( FORMAT_STRING_TIME_WITH_OFFSET, Locale.ENGLISH );
|
||||||
public static final DateTimeFormatter DATE_TIME_FORMATTER_TIME = DateTimeFormatter.ofPattern( FORMAT_STRING_TIME, Locale.ENGLISH );
|
public static final DateTimeFormatter DATE_TIME_FORMATTER_TIME = DateTimeFormatter.ofPattern( FORMAT_STRING_TIME, Locale.ENGLISH );
|
||||||
public static final DateTimeFormatter DATE_TIME_FORMATTER_TIMESTAMP_WITH_MILLIS = DateTimeFormatter.ofPattern(FORMAT_STRING_TIMESTAMP_WITH_MILLIS, Locale.ENGLISH );
|
public static final DateTimeFormatter DATE_TIME_FORMATTER_TIMESTAMP_WITH_MILLIS = DateTimeFormatter.ofPattern(
|
||||||
public static final DateTimeFormatter DATE_TIME_FORMATTER_TIMESTAMP_WITH_MICROS = DateTimeFormatter.ofPattern(FORMAT_STRING_TIMESTAMP_WITH_MICROS, Locale.ENGLISH );
|
FORMAT_STRING_TIMESTAMP_WITH_MILLIS,
|
||||||
|
Locale.ENGLISH
|
||||||
|
);
|
||||||
|
public static final DateTimeFormatter DATE_TIME_FORMATTER_TIMESTAMP_WITH_MICROS = DateTimeFormatter.ofPattern(
|
||||||
|
FORMAT_STRING_TIMESTAMP_WITH_MICROS,
|
||||||
|
Locale.ENGLISH
|
||||||
|
);
|
||||||
public static final DateTimeFormatter DATE_TIME_FORMATTER_TIMESTAMP_WITH_MILLIS_AND_OFFSET = DateTimeFormatter.ofPattern(
|
public static final DateTimeFormatter DATE_TIME_FORMATTER_TIMESTAMP_WITH_MILLIS_AND_OFFSET = DateTimeFormatter.ofPattern(
|
||||||
FORMAT_STRING_TIMESTAMP_WITH_MILLIS_AND_OFFSET, Locale.ENGLISH );
|
FORMAT_STRING_TIMESTAMP_WITH_MILLIS_AND_OFFSET,
|
||||||
|
Locale.ENGLISH
|
||||||
|
);
|
||||||
public static final DateTimeFormatter DATE_TIME_FORMATTER_TIMESTAMP_WITH_MICROS_AND_OFFSET = DateTimeFormatter.ofPattern(
|
public static final DateTimeFormatter DATE_TIME_FORMATTER_TIMESTAMP_WITH_MICROS_AND_OFFSET = DateTimeFormatter.ofPattern(
|
||||||
FORMAT_STRING_TIMESTAMP_WITH_MICROS_AND_OFFSET, Locale.ENGLISH );
|
FORMAT_STRING_TIMESTAMP_WITH_MICROS_AND_OFFSET,
|
||||||
|
Locale.ENGLISH
|
||||||
|
);
|
||||||
|
|
||||||
public static final String JDBC_ESCAPE_START_DATE = "{d '";
|
public static final String JDBC_ESCAPE_START_DATE = "{d '";
|
||||||
public static final String JDBC_ESCAPE_START_TIME = "{t '";
|
public static final String JDBC_ESCAPE_START_TIME = "{t '";
|
||||||
|
@ -78,6 +89,7 @@ public final class DateTimeUtils {
|
||||||
|
|
||||||
private static final ThreadLocal<SimpleDateFormat> LOCAL_DATE_FORMAT = ThreadLocal.withInitial( () -> new SimpleDateFormat( FORMAT_STRING_DATE, Locale.ENGLISH ) );
|
private static final ThreadLocal<SimpleDateFormat> LOCAL_DATE_FORMAT = ThreadLocal.withInitial( () -> new SimpleDateFormat( FORMAT_STRING_DATE, Locale.ENGLISH ) );
|
||||||
private static final ThreadLocal<SimpleDateFormat> LOCAL_TIME_FORMAT = ThreadLocal.withInitial( () -> new SimpleDateFormat( FORMAT_STRING_TIME, Locale.ENGLISH ) );
|
private static final ThreadLocal<SimpleDateFormat> LOCAL_TIME_FORMAT = ThreadLocal.withInitial( () -> new SimpleDateFormat( FORMAT_STRING_TIME, Locale.ENGLISH ) );
|
||||||
|
private static final ThreadLocal<SimpleDateFormat> TIME_WITH_OFFSET_FORMAT = ThreadLocal.withInitial( () -> new SimpleDateFormat( FORMAT_STRING_TIME_WITH_OFFSET, Locale.ENGLISH ) );
|
||||||
private static final ThreadLocal<SimpleDateFormat> TIMESTAMP_WITH_MILLIS_FORMAT = ThreadLocal.withInitial(
|
private static final ThreadLocal<SimpleDateFormat> TIMESTAMP_WITH_MILLIS_FORMAT = ThreadLocal.withInitial(
|
||||||
() -> new SimpleDateFormat(
|
() -> new SimpleDateFormat(
|
||||||
FORMAT_STRING_TIMESTAMP_WITH_MILLIS,
|
FORMAT_STRING_TIMESTAMP_WITH_MILLIS,
|
||||||
|
@ -113,7 +125,7 @@ public final class DateTimeUtils {
|
||||||
TemporalAccessor temporalAccessor,
|
TemporalAccessor temporalAccessor,
|
||||||
boolean supportsOffset,
|
boolean supportsOffset,
|
||||||
TimeZone jdbcTimeZone) {
|
TimeZone jdbcTimeZone) {
|
||||||
if ( temporalAccessor.isSupported(ChronoField.OFFSET_SECONDS) ) {
|
if ( temporalAccessor.isSupported( ChronoField.OFFSET_SECONDS ) ) {
|
||||||
if ( supportsOffset ) {
|
if ( supportsOffset ) {
|
||||||
DATE_TIME_FORMATTER_TIMESTAMP_WITH_MICROS_AND_OFFSET.formatTo( temporalAccessor, appender );
|
DATE_TIME_FORMATTER_TIMESTAMP_WITH_MICROS_AND_OFFSET.formatTo( temporalAccessor, appender );
|
||||||
}
|
}
|
||||||
|
@ -127,6 +139,23 @@ public final class DateTimeUtils {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if ( temporalAccessor instanceof Instant ) {
|
||||||
|
if ( supportsOffset ) {
|
||||||
|
DATE_TIME_FORMATTER_TIMESTAMP_WITH_MICROS_AND_OFFSET.formatTo(
|
||||||
|
( (Instant) temporalAccessor ).atZone( jdbcTimeZone.toZoneId() ),
|
||||||
|
appender
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DATE_TIME_FORMATTER_TIMESTAMP_WITH_MICROS.formatTo(
|
||||||
|
LocalDateTime.ofInstant(
|
||||||
|
(Instant) temporalAccessor,
|
||||||
|
jdbcTimeZone.toZoneId()
|
||||||
|
),
|
||||||
|
appender
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
DATE_TIME_FORMATTER_TIMESTAMP_WITH_MICROS.formatTo( temporalAccessor, appender );
|
DATE_TIME_FORMATTER_TIMESTAMP_WITH_MICROS.formatTo( temporalAccessor, appender );
|
||||||
}
|
}
|
||||||
|
@ -137,7 +166,7 @@ public final class DateTimeUtils {
|
||||||
TemporalAccessor temporalAccessor,
|
TemporalAccessor temporalAccessor,
|
||||||
boolean supportsOffset,
|
boolean supportsOffset,
|
||||||
TimeZone jdbcTimeZone) {
|
TimeZone jdbcTimeZone) {
|
||||||
if ( temporalAccessor.isSupported(ChronoField.OFFSET_SECONDS) ) {
|
if ( temporalAccessor.isSupported( ChronoField.OFFSET_SECONDS ) ) {
|
||||||
if ( supportsOffset ) {
|
if ( supportsOffset ) {
|
||||||
DATE_TIME_FORMATTER_TIMESTAMP_WITH_MILLIS_AND_OFFSET.formatTo( temporalAccessor, appender );
|
DATE_TIME_FORMATTER_TIMESTAMP_WITH_MILLIS_AND_OFFSET.formatTo( temporalAccessor, appender );
|
||||||
}
|
}
|
||||||
|
@ -151,6 +180,23 @@ public final class DateTimeUtils {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if ( temporalAccessor instanceof Instant ) {
|
||||||
|
if ( supportsOffset ) {
|
||||||
|
DATE_TIME_FORMATTER_TIMESTAMP_WITH_MILLIS_AND_OFFSET.formatTo(
|
||||||
|
( (Instant) temporalAccessor ).atZone( jdbcTimeZone.toZoneId() ),
|
||||||
|
appender
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DATE_TIME_FORMATTER_TIMESTAMP_WITH_MILLIS.formatTo(
|
||||||
|
LocalDateTime.ofInstant(
|
||||||
|
(Instant) temporalAccessor,
|
||||||
|
jdbcTimeZone.toZoneId()
|
||||||
|
),
|
||||||
|
appender
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
DATE_TIME_FORMATTER_TIMESTAMP_WITH_MILLIS.formatTo( temporalAccessor, appender );
|
DATE_TIME_FORMATTER_TIMESTAMP_WITH_MILLIS.formatTo( temporalAccessor, appender );
|
||||||
}
|
}
|
||||||
|
@ -165,18 +211,12 @@ public final class DateTimeUtils {
|
||||||
TemporalAccessor temporalAccessor,
|
TemporalAccessor temporalAccessor,
|
||||||
boolean supportsOffset,
|
boolean supportsOffset,
|
||||||
TimeZone jdbcTimeZone) {
|
TimeZone jdbcTimeZone) {
|
||||||
if ( temporalAccessor.isSupported(ChronoField.OFFSET_SECONDS) ) {
|
if ( temporalAccessor.isSupported( ChronoField.OFFSET_SECONDS ) ) {
|
||||||
if ( supportsOffset ) {
|
if ( supportsOffset ) {
|
||||||
DATE_TIME_FORMATTER_TIME_WITH_OFFSET.formatTo( temporalAccessor, appender );
|
DATE_TIME_FORMATTER_TIME_WITH_OFFSET.formatTo( temporalAccessor, appender );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DATE_TIME_FORMATTER_TIME.formatTo(
|
DATE_TIME_FORMATTER_TIME.formatTo( LocalTime.from( temporalAccessor ), appender );
|
||||||
LocalDateTime.ofInstant(
|
|
||||||
Instant.from( temporalAccessor ),
|
|
||||||
jdbcTimeZone.toZoneId()
|
|
||||||
),
|
|
||||||
appender
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -184,6 +224,10 @@ public final class DateTimeUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void appendAsLocalTime(SqlAppender appender, TemporalAccessor temporalAccessor) {
|
||||||
|
DATE_TIME_FORMATTER_TIME.formatTo( temporalAccessor, appender );
|
||||||
|
}
|
||||||
|
|
||||||
public static void appendAsTimestampWithMillis(SqlAppender appender, java.util.Date date, TimeZone jdbcTimeZone) {
|
public static void appendAsTimestampWithMillis(SqlAppender appender, java.util.Date date, TimeZone jdbcTimeZone) {
|
||||||
final SimpleDateFormat simpleDateFormat = TIMESTAMP_WITH_MILLIS_FORMAT.get();
|
final SimpleDateFormat simpleDateFormat = TIMESTAMP_WITH_MILLIS_FORMAT.get();
|
||||||
final TimeZone originalTimeZone = simpleDateFormat.getTimeZone();
|
final TimeZone originalTimeZone = simpleDateFormat.getTimeZone();
|
||||||
|
@ -220,7 +264,27 @@ public final class DateTimeUtils {
|
||||||
appender.appendSql( LOCAL_DATE_FORMAT.get().format( date ) );
|
appender.appendSql( LOCAL_DATE_FORMAT.get().format( date ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link #appendAsLocalTime(SqlAppender, Date)} instead
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public static void appendAsTime(SqlAppender appender, java.util.Date date) {
|
public static void appendAsTime(SqlAppender appender, java.util.Date date) {
|
||||||
|
appendAsLocalTime( appender, date );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void appendAsTime(SqlAppender appender, java.util.Date date, TimeZone jdbcTimeZone) {
|
||||||
|
final SimpleDateFormat simpleDateFormat = TIME_WITH_OFFSET_FORMAT.get();
|
||||||
|
final TimeZone originalTimeZone = simpleDateFormat.getTimeZone();
|
||||||
|
try {
|
||||||
|
simpleDateFormat.setTimeZone( jdbcTimeZone );
|
||||||
|
appender.appendSql( simpleDateFormat.format( date ) );
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
simpleDateFormat.setTimeZone( originalTimeZone );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void appendAsLocalTime(SqlAppender appender, Date date) {
|
||||||
appender.appendSql( LOCAL_TIME_FORMAT.get().format( date ) );
|
appender.appendSql( LOCAL_TIME_FORMAT.get().format( date ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,11 +328,19 @@ public final class DateTimeUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link #appendAsLocalTime(SqlAppender, Calendar)} instead
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public static void appendAsTime(SqlAppender appender, java.util.Calendar calendar) {
|
public static void appendAsTime(SqlAppender appender, java.util.Calendar calendar) {
|
||||||
final SimpleDateFormat simpleDateFormat = LOCAL_TIME_FORMAT.get();
|
appendAsLocalTime( appender, calendar );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void appendAsTime(SqlAppender appender, java.util.Calendar calendar, TimeZone jdbcTimeZone) {
|
||||||
|
final SimpleDateFormat simpleDateFormat = TIME_WITH_OFFSET_FORMAT.get();
|
||||||
final TimeZone originalTimeZone = simpleDateFormat.getTimeZone();
|
final TimeZone originalTimeZone = simpleDateFormat.getTimeZone();
|
||||||
try {
|
try {
|
||||||
simpleDateFormat.setTimeZone( calendar.getTimeZone() );
|
simpleDateFormat.setTimeZone( jdbcTimeZone );
|
||||||
appender.appendSql( simpleDateFormat.format( calendar.getTime() ) );
|
appender.appendSql( simpleDateFormat.format( calendar.getTime() ) );
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
@ -276,4 +348,8 @@ public final class DateTimeUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void appendAsLocalTime(SqlAppender appender, Calendar calendar) {
|
||||||
|
appender.appendSql( LOCAL_TIME_FORMAT.get().format( calendar.getTime() ) );
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ import org.hibernate.type.descriptor.ValueBinder;
|
||||||
import org.hibernate.type.descriptor.ValueExtractor;
|
import org.hibernate.type.descriptor.ValueExtractor;
|
||||||
import org.hibernate.type.descriptor.WrapperOptions;
|
import org.hibernate.type.descriptor.WrapperOptions;
|
||||||
import org.hibernate.type.descriptor.java.JavaType;
|
import org.hibernate.type.descriptor.java.JavaType;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.internal.JdbcLiteralFormatterUUIDData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specialized type mapping for {@link UUID} and the UUID SQL data type.
|
* Specialized type mapping for {@link UUID} and the UUID SQL data type.
|
||||||
|
@ -50,6 +51,11 @@ public class UUIDJdbcType implements JdbcType {
|
||||||
return UUID.class;
|
return UUID.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> JdbcLiteralFormatter<T> getJdbcLiteralFormatter(JavaType<T> javaType) {
|
||||||
|
return new JdbcLiteralFormatterUUIDData<>( javaType );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <X> ValueBinder<X> getBinder(JavaType<X> javaType) {
|
public <X> ValueBinder<X> getBinder(JavaType<X> javaType) {
|
||||||
return new BasicBinder<>( javaType, this ) {
|
return new BasicBinder<>( javaType, this ) {
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.type.descriptor.jdbc.internal;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.hibernate.dialect.Dialect;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||||
|
import org.hibernate.type.descriptor.WrapperOptions;
|
||||||
|
import org.hibernate.type.descriptor.java.JavaType;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.spi.BasicJdbcLiteralFormatter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link org.hibernate.type.descriptor.jdbc.JdbcLiteralFormatter}
|
||||||
|
* implementation for handling UUID values
|
||||||
|
*/
|
||||||
|
public class JdbcLiteralFormatterUUIDData<T> extends BasicJdbcLiteralFormatter<T> {
|
||||||
|
|
||||||
|
public JdbcLiteralFormatterUUIDData(JavaType<T> javaType) {
|
||||||
|
super( javaType );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void appendJdbcLiteral(SqlAppender appender, Object value, Dialect dialect, WrapperOptions wrapperOptions) {
|
||||||
|
final UUID literalValue = unwrap( value, UUID.class, wrapperOptions );
|
||||||
|
dialect.appendUUIDLiteral( appender, literalValue );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,106 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.orm.test.type.contributor;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.sql.Date;
|
||||||
|
import java.sql.Time;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalTime;
|
||||||
|
import java.time.Year;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
|
import java.util.Currency;
|
||||||
|
import java.util.GregorianCalendar;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.hibernate.query.criteria.HibernateCriteriaBuilder;
|
||||||
|
import org.hibernate.query.criteria.JpaCriteriaQuery;
|
||||||
|
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
|
import org.hibernate.testing.orm.domain.StandardDomainModel;
|
||||||
|
import org.hibernate.testing.orm.domain.gambit.BasicEntity;
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
|
||||||
|
@ServiceRegistry
|
||||||
|
@DomainModel( standardModels = StandardDomainModel.GAMBIT )
|
||||||
|
@SessionFactory
|
||||||
|
@TestForIssue(jiraKey = "HHH-15590")
|
||||||
|
public class LiteralRenderingTest {
|
||||||
|
|
||||||
|
public static List<Object> literalValues() throws Exception {
|
||||||
|
return List.<Object>of(
|
||||||
|
true,
|
||||||
|
(byte) 1,
|
||||||
|
(short) 1,
|
||||||
|
(int) 1,
|
||||||
|
(long) 1,
|
||||||
|
1f,
|
||||||
|
1d,
|
||||||
|
'c',
|
||||||
|
"string",
|
||||||
|
LocalDate.parse( "2000-01-01" ),
|
||||||
|
LocalDateTime.parse( "2000-01-01T01:01:01" ),
|
||||||
|
LocalTime.parse( "01:01:01" ),
|
||||||
|
LocalDateTime.parse( "2000-01-01T01:01:01" ).toInstant( ZoneOffset.UTC ),
|
||||||
|
Date.valueOf( LocalDate.parse( "2000-01-01" ) ),
|
||||||
|
Timestamp.valueOf( LocalDateTime.parse( "2000-01-01T01:01:01" ) ),
|
||||||
|
Time.valueOf( LocalTime.parse( "01:01:01" ) ),
|
||||||
|
java.util.Date.from( LocalDateTime.parse( "2000-01-01T01:01:01" ).toInstant( ZoneOffset.UTC ) ),
|
||||||
|
GregorianCalendar.from( LocalDateTime.parse( "2000-01-01T01:01:01" ).atZone( ZoneOffset.UTC ) ),
|
||||||
|
LocalDateTime.parse( "2000-01-01T01:01:01" ).atZone( ZoneOffset.UTC ),
|
||||||
|
LocalDateTime.parse( "2000-01-01T01:01:01" ).atOffset( ZoneOffset.UTC ),
|
||||||
|
LocalTime.parse( "01:01:01" ).atOffset( ZoneOffset.UTC ),
|
||||||
|
new char[]{ 'c' },
|
||||||
|
new byte[]{ 1 },
|
||||||
|
new Character[]{ 'c' },
|
||||||
|
new Byte[]{ 1 },
|
||||||
|
Locale.ENGLISH,
|
||||||
|
UUID.fromString( "53886a8a-7082-4879-b430-25cb94415be8" ),
|
||||||
|
ZoneId.of( "UTC" ),
|
||||||
|
BigDecimal.ONE,
|
||||||
|
BigInteger.ONE,
|
||||||
|
Year.of( 2000 ),
|
||||||
|
TimeZone.getTimeZone( "UTC" ),
|
||||||
|
Currency.getInstance( "EUR" ),
|
||||||
|
Duration.ofDays( 1 ),
|
||||||
|
InetAddress.getByName( "127.0.0.1" ),
|
||||||
|
new URL( "https://hibernate.org" ),
|
||||||
|
Boolean.class
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("literalValues")
|
||||||
|
public void testIdVersionFunctions(Object literalValue, SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
session -> {
|
||||||
|
HibernateCriteriaBuilder cb = session.getCriteriaBuilder();
|
||||||
|
JpaCriteriaQuery<Object> query = cb.createQuery();
|
||||||
|
query.from( BasicEntity.class );
|
||||||
|
query.select( cb.literal( 1 ) );
|
||||||
|
query.where( cb.isNotNull( cb.literal( literalValue ) ) );
|
||||||
|
session.createQuery( query ).list();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -37,7 +37,7 @@ public class JUnitHelper {
|
||||||
|
|
||||||
public static boolean supportsParameterInjection(ParameterContext parameterContext, Class<?>... supportedTypes) {
|
public static boolean supportsParameterInjection(ParameterContext parameterContext, Class<?>... supportedTypes) {
|
||||||
for ( Class<?> supportedType : supportedTypes ) {
|
for ( Class<?> supportedType : supportedTypes ) {
|
||||||
if ( parameterContext.getParameter().getType().isAssignableFrom( supportedType ) ) {
|
if ( supportedType.isAssignableFrom( parameterContext.getParameter().getType() ) ) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue