org.hibernate.query.internal.BindingTypeHelper Maven / Gradle / Ivy
/*
* 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 .
*/
package org.hibernate.query.internal;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.ZonedDateTime;
import java.util.Calendar;
import javax.persistence.TemporalType;
import org.hibernate.type.BasicType;
import org.hibernate.type.CalendarDateType;
import org.hibernate.type.CalendarTimeType;
import org.hibernate.type.CalendarType;
import org.hibernate.type.InstantType;
import org.hibernate.type.OffsetDateTimeType;
import org.hibernate.type.OffsetTimeType;
import org.hibernate.type.TimestampType;
import org.hibernate.type.Type;
import org.hibernate.type.ZonedDateTimeType;
/**
* @author Steve Ebersole
*/
public class BindingTypeHelper {
/**
* Singleton access
*/
public static final BindingTypeHelper INSTANCE = new BindingTypeHelper();
private BindingTypeHelper() {
}
public BasicType determineTypeForTemporalType(TemporalType temporalType, Type baseType, Object bindValue) {
// todo : for 6.0 make TemporalType part of org.hibernate.type.descriptor.java.JdbcRecommendedSqlTypeMappingContext
// then we can just ask the org.hibernate.type.basic.BasicTypeFactory to handle this based on its registry
//
// - or for 6.0 make TemporalType part of the state for those BasicType impls dealing with date/time types
//
// - or for 6.0 make TemporalType part of Binder contract
//
// - or add a org.hibernate.type.TemporalType#getVariant(TemporalType)
//
// - or ...
// todo : (5.2) review Java type handling for sanity. This part was done quickly ;)
final Class javaType;
// Determine the "value java type" :
// prefer to leverage the bindValue java type (if bindValue not null),
// followed by the java type reported by the baseType,
// fallback to java.sql.Timestamp
if ( bindValue != null ) {
javaType = bindValue.getClass();
}
else if ( baseType != null ) {
javaType = baseType.getReturnedClass();
}
else {
javaType = java.sql.Timestamp.class;
}
switch ( temporalType ) {
case TIMESTAMP: {
return resolveTimestampTemporalTypeVariant( javaType, baseType );
}
case DATE: {
return resolveDateTemporalTypeVariant( javaType, baseType );
}
case TIME: {
return resolveTimeTemporalTypeVariant( javaType, baseType );
}
default: {
throw new IllegalArgumentException( "Unexpected TemporalType [" + temporalType + "]; expecting TIMESTAMP, DATE or TIME" );
}
}
}
public BasicType resolveTimestampTemporalTypeVariant(Class javaType, Type baseType) {
// prefer to use any Type already known - interprets TIMESTAMP as "no narrowing"
if ( baseType != null && baseType instanceof BasicType ) {
return (BasicType) baseType;
}
if ( Calendar.class.isAssignableFrom( javaType ) ) {
return CalendarType.INSTANCE;
}
if ( java.util.Date.class.isAssignableFrom( javaType ) ) {
return TimestampType.INSTANCE;
}
if ( Instant.class.isAssignableFrom( javaType ) ) {
return InstantType.INSTANCE;
}
if ( OffsetDateTime.class.isAssignableFrom( javaType ) ) {
return OffsetDateTimeType.INSTANCE;
}
if ( ZonedDateTime.class.isAssignableFrom( javaType ) ) {
return ZonedDateTimeType.INSTANCE;
}
if ( OffsetTime.class.isAssignableFrom( javaType ) ) {
return OffsetTimeType.INSTANCE;
}
throw new IllegalArgumentException( "Unsure how to handle given Java type [" + javaType.getName() + "] as TemporalType#TIMESTAMP" );
}
@SuppressWarnings("unchecked")
public BasicType resolveDateTemporalTypeVariant(Class javaType, Type baseType) {
// prefer to use any Type already known
if ( baseType != null && baseType instanceof BasicType ) {
if ( baseType.getReturnedClass().isAssignableFrom( javaType ) ) {
return (BasicType) baseType;
}
}
if ( Calendar.class.isAssignableFrom( javaType ) ) {
return CalendarDateType.INSTANCE;
}
if ( java.util.Date.class.isAssignableFrom( javaType ) ) {
return TimestampType.INSTANCE;
}
if ( Instant.class.isAssignableFrom( javaType ) ) {
return OffsetDateTimeType.INSTANCE;
}
if ( OffsetDateTime.class.isAssignableFrom( javaType ) ) {
return OffsetDateTimeType.INSTANCE;
}
if ( ZonedDateTime.class.isAssignableFrom( javaType ) ) {
return ZonedDateTimeType.INSTANCE;
}
throw new IllegalArgumentException( "Unsure how to handle given Java type [" + javaType.getName() + "] as TemporalType#DATE" );
}
public BasicType resolveTimeTemporalTypeVariant(Class javaType, Type baseType) {
if ( Calendar.class.isAssignableFrom( javaType ) ) {
return CalendarTimeType.INSTANCE;
}
if ( java.util.Date.class.isAssignableFrom( javaType ) ) {
return TimestampType.INSTANCE;
}
throw new IllegalArgumentException( "Unsure how to handle given Java type [" + javaType.getName() + "] as TemporalType#TIME" );
}
}