diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/AttributeFactory.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/AttributeFactory.java index ad4fbe8dfa..7b38fa325a 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/AttributeFactory.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/AttributeFactory.java @@ -235,18 +235,12 @@ public class AttributeFactory { public static DomainType determineSimpleType(ValueContext typeContext, MetadataContext context) { switch ( typeContext.getValueClassification() ) { case BASIC: { - Class returnedClass = typeContext.getJpaBindableType(); - if ( returnedClass.isAssignableFrom( Object.class ) ) { - final SimpleValue simpleValue = (SimpleValue) typeContext.getHibernateValue(); - if ( simpleValue.getTypeParameters() != null && typeContext.getAttributeMetadata() - .getOwnerType() instanceof EntityDomainType ) { - // Due to how generics work with Java, the type of generic fields will always - // be reported as Object. We need to resolve type based on the actual property - // value for basic attributes in entities which specify concrete type parameters. - returnedClass = simpleValue.getType().getReturnedClass(); - } + final Class jpaBindableType = typeContext.getJpaBindableType(); + if ( jpaBindableType.isPrimitive() ) { + // Special BasicDomainType necessary for primitive types in the JPA metamodel + return (DomainType) context.resolveBasicType( jpaBindableType ); } - return context.resolveBasicType( returnedClass ); + return (DomainType) typeContext.getHibernateValue().getType(); } case ENTITY: { final org.hibernate.type.Type type = typeContext.getHibernateValue().getType(); @@ -555,45 +549,6 @@ public class AttributeFactory { } } - protected Class accountForPrimitiveTypes(Class declaredType) { - return accountForPrimitiveTypes( declaredType, context ); - } - - public static Class accountForPrimitiveTypes(Class declaredType, MetadataContext metadataContext) { -// if ( !declaredType.isPrimitive() ) { -// return declaredType; -// } -// -// if ( Boolean.TYPE.equals( declaredType ) ) { -// return (Class) Boolean.class; -// } -// if ( Character.TYPE.equals( declaredType ) ) { -// return (Class) Character.class; -// } -// if( Byte.TYPE.equals( declaredType ) ) { -// return (Class) Byte.class; -// } -// if ( Short.TYPE.equals( declaredType ) ) { -// return (Class) Short.class; -// } -// if ( Integer.TYPE.equals( declaredType ) ) { -// return (Class) Integer.class; -// } -// if ( Long.TYPE.equals( declaredType ) ) { -// return (Class) Long.class; -// } -// if ( Float.TYPE.equals( declaredType ) ) { -// return (Class) Float.class; -// } -// if ( Double.TYPE.equals( declaredType ) ) { -// return (Class) Double.class; -// } -// -// throw new IllegalArgumentException( "Unexpected type [" + declaredType + "]" ); - // if the field is defined as int, return int not Integer... - return declaredType; - } - public static ParameterizedType getSignatureType(Member member) { final java.lang.reflect.Type type; if ( member instanceof Field ) { diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/BaseAttributeMetadata.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/BaseAttributeMetadata.java index 18f833728c..5cfea74ddc 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/BaseAttributeMetadata.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/BaseAttributeMetadata.java @@ -54,8 +54,7 @@ public abstract class BaseAttributeMetadata implements AttributeMetadata temporalJtd = (TemporalJavaType) sqmExpressible.getExpressibleJavaType(); if ( temporalJtd.getPrecision() != precision ) { final TypeConfiguration typeConfiguration = sessionFactory.getTypeConfiguration(); + final TemporalJavaType temporalTypeForPrecision; + // Special case java.util.Date, because TemporalJavaType#resolveTypeForPrecision doesn't support widening, + // since the main purpose of that method is to determine the final java type based on the reflective type + // + the explicit @Temporal(TemporalType...) configuration + if ( java.util.Date.class.isAssignableFrom( temporalJtd.getJavaTypeClass() ) ) { + //noinspection unchecked + temporalTypeForPrecision = (TemporalJavaType) typeConfiguration.getJavaTypeRegistry().getDescriptor( + TemporalJavaType.resolveJavaTypeClass( precision ) + ); + } + else { + temporalTypeForPrecision = temporalJtd.resolveTypeForPrecision( + precision, + typeConfiguration + ); + } return typeConfiguration.getBasicTypeRegistry().resolve( - temporalJtd.resolveTypeForPrecision( precision, typeConfiguration ), + temporalTypeForPrecision, TemporalJavaType.resolveJdbcTypeCode( precision ) ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/spi/AbstractCommonQueryContract.java b/hibernate-core/src/main/java/org/hibernate/query/spi/AbstractCommonQueryContract.java index 5b6d859a9e..bf01e70442 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/spi/AbstractCommonQueryContract.java +++ b/hibernate-core/src/main/java/org/hibernate/query/spi/AbstractCommonQueryContract.java @@ -637,7 +637,7 @@ public abstract class AbstractCommonQueryContract implements CommonQueryContract try { //noinspection rawtypes final QueryParameterImplementor parameter = getParameterMetadata().getQueryParameter( name ); - if ( !parameter.getParameterType().isAssignableFrom( type ) ) { + if ( !type.isAssignableFrom( parameter.getParameterType() ) ) { throw new IllegalArgumentException( "The type [" + parameter.getParameterType().getName() + "] associated with the parameter corresponding to name [" + name + @@ -668,7 +668,7 @@ public abstract class AbstractCommonQueryContract implements CommonQueryContract try { final QueryParameterImplementor parameter = getParameterMetadata().getQueryParameter( position ); - if ( !parameter.getParameterType().isAssignableFrom( type ) ) { + if ( !type.isAssignableFrom( parameter.getParameterType() ) ) { throw new IllegalArgumentException( "The type [" + parameter.getParameterType().getName() + "] associated with the parameter corresponding to position [" + position + diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/TemporalJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/TemporalJavaType.java index 8431a55e9a..528b996048 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/TemporalJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/TemporalJavaType.java @@ -33,6 +33,18 @@ public interface TemporalJavaType extends BasicJavaType { throw new UnsupportedOperationException( "Unsupported precision: " + requestedTemporalPrecision ); } + static Class resolveJavaTypeClass(TemporalType requestedTemporalPrecision) { + switch ( requestedTemporalPrecision ) { + case DATE: + return java.sql.Date.class; + case TIME: + return java.sql.Time.class; + case TIMESTAMP: + return java.sql.Timestamp.class; + } + throw new UnsupportedOperationException( "Unsupported precision: " + requestedTemporalPrecision ); + } + /** * The precision represented by this type */ diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/query/QueryTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/query/QueryTest.java index b2e6237e7f..f43c72e7f2 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/query/QueryTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/query/QueryTest.java @@ -1037,7 +1037,7 @@ public class QueryTest extends BaseEntityManagerFunctionalTestCase { try { Query query = em.createQuery( "select w from " + Wallet.class.getName() + " w where w.marketEntrance = :me" ); Parameter parameter = query.getParameter( "me", Date.class ); - assertEquals( parameter.getParameterType(), Date.class ); + assertEquals( parameter.getParameterType(), java.sql.Timestamp.class ); query.setParameter( "me", new Date() ); query.setParameter( "me", new Date(), TemporalType.DATE );