Search in sources :

Example 1 with TemporalJavaType

use of org.hibernate.type.descriptor.java.TemporalJavaType in project hibernate-orm by hibernate.

the class InferredBasicValueResolver method from.

public static <T> BasicValue.Resolution<T> from(BasicJavaType<T> explicitJavaType, JdbcType explicitJdbcType, Type resolvedJavaType, Supplier<JavaType<T>> reflectedJtdResolver, JdbcTypeIndicators stdIndicators, Table table, Selectable selectable, String ownerName, String propertyName, TypeConfiguration typeConfiguration) {
    final JavaType<T> reflectedJtd = reflectedJtdResolver.get();
    // NOTE : the distinction that is made below wrt `explicitJavaType` and `reflectedJtd` is
    // needed temporarily to trigger "legacy resolution" versus "ORM6 resolution.  Yes, it
    // makes the code a little more complicated but the benefit is well worth it - saving memory
    final BasicType<T> jdbcMapping;
    final BasicType<T> legacyType;
    if (explicitJavaType != null) {
        if (explicitJdbcType != null) {
            // we also have an explicit JdbcType
            jdbcMapping = typeConfiguration.getBasicTypeRegistry().resolve(explicitJavaType, explicitJdbcType);
            legacyType = jdbcMapping;
        } else {
            if (explicitJavaType instanceof TemporalJavaType) {
                return fromTemporal((TemporalJavaType<T>) explicitJavaType, null, null, resolvedJavaType, stdIndicators, typeConfiguration);
            }
            // we need to infer the JdbcType and use that to build the value-mapping
            final JdbcType inferredJdbcType = explicitJavaType.getRecommendedJdbcType(stdIndicators);
            if (inferredJdbcType instanceof ObjectJdbcType) {
                if (explicitJavaType instanceof EnumJavaType) {
                    return fromEnum((EnumJavaType) reflectedJtd, explicitJavaType, null, stdIndicators, typeConfiguration);
                } else if (explicitJavaType instanceof TemporalJavaType) {
                    return fromTemporal((TemporalJavaType<T>) reflectedJtd, explicitJavaType, null, resolvedJavaType, stdIndicators, typeConfiguration);
                } else if (explicitJavaType instanceof SerializableJavaType || explicitJavaType.getJavaType() instanceof Serializable) {
                    legacyType = new SerializableType(explicitJavaType);
                    jdbcMapping = legacyType;
                } else {
                    jdbcMapping = typeConfiguration.getBasicTypeRegistry().resolve(explicitJavaType, inferredJdbcType);
                    legacyType = jdbcMapping;
                }
            } else {
                jdbcMapping = typeConfiguration.getBasicTypeRegistry().resolve(explicitJavaType, inferredJdbcType);
                legacyType = jdbcMapping;
            }
        }
    } else if (reflectedJtd != null) {
        // we were able to determine the "reflected java-type"
        if (explicitJdbcType != null) {
            // we also have an explicit JdbcType
            jdbcMapping = typeConfiguration.getBasicTypeRegistry().resolve(reflectedJtd, explicitJdbcType);
            legacyType = jdbcMapping;
        } else {
            if (reflectedJtd instanceof EnumJavaType) {
                return fromEnum((EnumJavaType) reflectedJtd, null, null, stdIndicators, typeConfiguration);
            } else if (reflectedJtd instanceof TemporalJavaType) {
                return fromTemporal((TemporalJavaType<T>) reflectedJtd, null, null, resolvedJavaType, stdIndicators, typeConfiguration);
            } else {
                // see if there is a registered BasicType for this JavaType and, if so, use it.
                // this mimics the legacy handling
                final BasicType<T> registeredType = typeConfiguration.getBasicTypeRegistry().getRegisteredType(reflectedJtd.getJavaType());
                if (registeredType != null) {
                    // so here is the legacy resolution
                    legacyType = resolveSqlTypeIndicators(stdIndicators, registeredType, reflectedJtd);
                    jdbcMapping = legacyType;
                } else {
                    // there was not a "legacy" BasicType registration,  so use `JavaType#getRecommendedJdbcType`, if
                    // one, to create a mapping
                    final JdbcType recommendedJdbcType = reflectedJtd.getRecommendedJdbcType(stdIndicators);
                    if (recommendedJdbcType != null) {
                        jdbcMapping = typeConfiguration.getBasicTypeRegistry().resolve(reflectedJtd, recommendedJdbcType);
                        legacyType = jdbcMapping;
                    } else if (reflectedJtd instanceof SerializableJavaType || Serializable.class.isAssignableFrom(reflectedJtd.getJavaTypeClass())) {
                        legacyType = new SerializableType(reflectedJtd);
                        jdbcMapping = legacyType;
                    } else {
                        // let this fall through to the exception creation below
                        legacyType = null;
                        jdbcMapping = null;
                    }
                }
            }
        }
    } else {
        if (explicitJdbcType != null) {
            // we have an explicit STD, but no JTD - infer JTD
            // - NOTE : yes its an odd case, but its easy to implement here, so...
            Integer length = null;
            Integer scale = null;
            if (selectable instanceof Column) {
                final Column column = (Column) selectable;
                if (column.getPrecision() != null && column.getPrecision() > 0) {
                    length = column.getPrecision();
                    scale = column.getScale();
                } else if (column.getLength() != null) {
                    if (column.getLength() > (long) Integer.MAX_VALUE) {
                        length = Integer.MAX_VALUE;
                    } else {
                        length = column.getLength().intValue();
                    }
                }
            }
            final BasicJavaType<T> recommendedJtd = explicitJdbcType.getJdbcRecommendedJavaTypeMapping(length, scale, typeConfiguration);
            jdbcMapping = resolveSqlTypeIndicators(stdIndicators, typeConfiguration.getBasicTypeRegistry().resolve(recommendedJtd, explicitJdbcType), recommendedJtd);
            legacyType = jdbcMapping;
        } else {
            throw new MappingException("Could not determine JavaType nor JdbcType to use" + " for BasicValue: owner = " + ownerName + "; property = " + propertyName + "; table = " + table.getName() + "; column = " + selectable.getText());
        }
    }
    if (jdbcMapping == null) {
        throw new MappingException("Could not determine JavaType nor JdbcType to use" + "" + " for " + ((BasicValue) stdIndicators).getResolvedJavaType() + "; table = " + table.getName() + "; column = " + selectable.getText());
    }
    return new InferredBasicValueResolution<>(jdbcMapping, jdbcMapping.getJavaTypeDescriptor(), jdbcMapping.getJavaTypeDescriptor(), jdbcMapping.getJdbcType(), null, legacyType, null);
}
Also used : Serializable(java.io.Serializable) SerializableJavaType(org.hibernate.type.descriptor.java.SerializableJavaType) SerializableType(org.hibernate.type.SerializableType) JdbcType(org.hibernate.type.descriptor.jdbc.JdbcType) ObjectJdbcType(org.hibernate.type.descriptor.jdbc.ObjectJdbcType) MappingException(org.hibernate.MappingException) BasicValue(org.hibernate.mapping.BasicValue) TemporalJavaType(org.hibernate.type.descriptor.java.TemporalJavaType) BasicJavaType(org.hibernate.type.descriptor.java.BasicJavaType) ObjectJdbcType(org.hibernate.type.descriptor.jdbc.ObjectJdbcType) EnumJavaType(org.hibernate.type.descriptor.java.EnumJavaType) Column(org.hibernate.mapping.Column)

Example 2 with TemporalJavaType

use of org.hibernate.type.descriptor.java.TemporalJavaType in project hibernate-orm by hibernate.

the class InferredBasicValueResolver method fromTemporal.

public static <T> InferredBasicValueResolution<T, T> fromTemporal(TemporalJavaType<T> reflectedJtd, BasicJavaType<?> explicitJavaType, JdbcType explicitJdbcType, Type resolvedJavaType, JdbcTypeIndicators stdIndicators, TypeConfiguration typeConfiguration) {
    final TemporalType requestedTemporalPrecision = stdIndicators.getTemporalPrecision();
    if (explicitJavaType != null) {
        if (!(explicitJavaType instanceof TemporalJavaType)) {
            throw new MappingException("Explicit JavaType [" + explicitJavaType + "] defined for temporal value must implement TemporalJavaType");
        }
        @SuppressWarnings("unchecked") final TemporalJavaType<T> explicitTemporalJtd = (TemporalJavaType<T>) explicitJavaType;
        if (requestedTemporalPrecision != null && explicitTemporalJtd.getPrecision() != requestedTemporalPrecision) {
            throw new MappingException("Temporal precision (`jakarta.persistence.TemporalType`) mismatch... requested precision = " + requestedTemporalPrecision + "; explicit JavaType (`" + explicitTemporalJtd + "`) precision = " + explicitTemporalJtd.getPrecision());
        }
        final JdbcType jdbcType = explicitJdbcType != null ? explicitJdbcType : explicitTemporalJtd.getRecommendedJdbcType(stdIndicators);
        final BasicType<T> jdbcMapping = typeConfiguration.getBasicTypeRegistry().resolve(explicitTemporalJtd, jdbcType);
        return new InferredBasicValueResolution<>(jdbcMapping, explicitTemporalJtd, explicitTemporalJtd, jdbcType, null, jdbcMapping, explicitTemporalJtd.getMutabilityPlan());
    }
    if (explicitJdbcType != null) {
        final TemporalJavaType<T> jtd;
        if (requestedTemporalPrecision != null) {
            jtd = reflectedJtd.resolveTypeForPrecision(requestedTemporalPrecision, typeConfiguration);
        } else {
            jtd = reflectedJtd;
        }
        final BasicType<T> jdbcMapping = typeConfiguration.getBasicTypeRegistry().resolve(jtd, explicitJdbcType);
        return new InferredBasicValueResolution<>(jdbcMapping, jtd, jtd, explicitJdbcType, null, jdbcMapping, jtd.getMutabilityPlan());
    }
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // Case #3 - no explicit JavaType or JdbcType
    // 
    // - for the moment continue to use the legacy resolution to registered
    // BasicType
    final BasicType<T> basicType;
    if (requestedTemporalPrecision != null && requestedTemporalPrecision != reflectedJtd.getPrecision()) {
        basicType = typeConfiguration.getBasicTypeRegistry().resolve(reflectedJtd.resolveTypeForPrecision(requestedTemporalPrecision, typeConfiguration), TemporalJavaType.resolveJdbcTypeCode(requestedTemporalPrecision));
    } else {
        basicType = typeConfiguration.getBasicTypeRegistry().resolve(reflectedJtd, reflectedJtd.getRecommendedJdbcType(stdIndicators));
    }
    return new InferredBasicValueResolution<>(basicType, basicType.getJavaTypeDescriptor(), basicType.getJavaTypeDescriptor(), basicType.getJdbcType(), null, basicType, reflectedJtd.getMutabilityPlan());
}
Also used : TemporalJavaType(org.hibernate.type.descriptor.java.TemporalJavaType) JdbcType(org.hibernate.type.descriptor.jdbc.JdbcType) ObjectJdbcType(org.hibernate.type.descriptor.jdbc.ObjectJdbcType) TemporalType(jakarta.persistence.TemporalType) MappingException(org.hibernate.MappingException)

Example 3 with TemporalJavaType

use of org.hibernate.type.descriptor.java.TemporalJavaType in project hibernate-orm by hibernate.

the class DatePrecisionTests method verifyMapping.

@Test
public void verifyMapping(SessionFactoryScope scope) {
    final MappingMetamodelImplementor mappingMetamodel = scope.getSessionFactory().getRuntimeMetamodels().getMappingMetamodel();
    final EntityPersister entityDescriptor = mappingMetamodel.findEntityDescriptor(EntityOfDates.class);
    {
        final BasicAttributeMapping attribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping("dateAsTimestamp");
        final JdbcMapping jdbcMapping = attribute.getJdbcMapping();
        final TemporalJavaType jtd = (TemporalJavaType) jdbcMapping.getJavaTypeDescriptor();
        assertThat(jtd, is(attribute.getJavaType()));
        assertThat(jtd.getJavaTypeClass(), equalTo(Timestamp.class));
        assertThat(jtd.getPrecision(), equalTo(TemporalType.TIMESTAMP));
        assertThat(jdbcMapping.getJdbcType().getJdbcTypeCode(), equalTo(Types.TIMESTAMP));
    }
    {
        final BasicAttributeMapping attribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping("dateAsDate");
        final JdbcMapping jdbcMapping = attribute.getJdbcMapping();
        final TemporalJavaType jtd = (TemporalJavaType) jdbcMapping.getJavaTypeDescriptor();
        assertThat(jtd, is(attribute.getJavaType()));
        assertThat(jtd.getJavaTypeClass(), equalTo(java.sql.Date.class));
        assertThat(jtd.getPrecision(), equalTo(TemporalType.DATE));
        assertThat(jdbcMapping.getJdbcType().getJdbcTypeCode(), equalTo(Types.DATE));
    }
    {
        final BasicAttributeMapping attribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping("dateAsTime");
        final JdbcMapping jdbcMapping = attribute.getJdbcMapping();
        final TemporalJavaType jtd = (TemporalJavaType) jdbcMapping.getJavaTypeDescriptor();
        assertThat(jtd, is(attribute.getJavaType()));
        assertThat(jtd.getJavaTypeClass(), equalTo(Time.class));
        assertThat(jtd.getPrecision(), equalTo(TemporalType.TIME));
        assertThat(jdbcMapping.getJdbcType().getJdbcTypeCode(), equalTo(Types.TIME));
    }
    // check persistence operations
    scope.inTransaction((session) -> {
        session.persist(new EntityOfDates(1, Date.from(Instant.now()), Date.from(Instant.now()), Date.from(Instant.now())));
    });
    scope.inTransaction((session) -> {
        session.find(EntityOfDates.class, 1);
    });
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) TemporalJavaType(org.hibernate.type.descriptor.java.TemporalJavaType) JdbcMapping(org.hibernate.metamodel.mapping.JdbcMapping) BasicAttributeMapping(org.hibernate.metamodel.mapping.internal.BasicAttributeMapping) MappingMetamodelImplementor(org.hibernate.metamodel.spi.MappingMetamodelImplementor) Test(org.junit.jupiter.api.Test)

Example 4 with TemporalJavaType

use of org.hibernate.type.descriptor.java.TemporalJavaType in project hibernate-orm by hibernate.

the class BindingTypeHelper method resolveBindType.

public JdbcMapping resolveBindType(Object value, JdbcMapping baseType, TypeConfiguration typeConfiguration) {
    if (value == null || !(baseType.getJavaTypeDescriptor() instanceof TemporalJavaType<?>)) {
        return baseType;
    }
    final Class<?> javaType = value.getClass();
    final TemporalType temporalType = ((TemporalJavaType<?>) baseType.getJavaTypeDescriptor()).getPrecision();
    switch(temporalType) {
        case TIMESTAMP:
            {
                return (JdbcMapping) resolveTimestampTemporalTypeVariant(javaType, (BindableType<?>) baseType, typeConfiguration);
            }
        case DATE:
            {
                return (JdbcMapping) resolveDateTemporalTypeVariant(javaType, (BindableType<?>) baseType, typeConfiguration);
            }
        case TIME:
            {
                return (JdbcMapping) resolveTimeTemporalTypeVariant(javaType, (BindableType<?>) baseType, typeConfiguration);
            }
        default:
            {
                throw new IllegalArgumentException("Unexpected TemporalType [" + temporalType + "]; expecting TIMESTAMP, DATE or TIME");
            }
    }
}
Also used : TemporalJavaType(org.hibernate.type.descriptor.java.TemporalJavaType) TemporalType(jakarta.persistence.TemporalType)

Example 5 with TemporalJavaType

use of org.hibernate.type.descriptor.java.TemporalJavaType in project hibernate-orm by hibernate.

the class BindingTypeHelper method resolveTemporalPrecision.

public <T> BindableType<T> resolveTemporalPrecision(TemporalType precision, BindableType<T> declaredParameterType, SessionFactoryImplementor sessionFactory) {
    if (precision != null) {
        final SqmExpressible<T> sqmExpressible = declaredParameterType.resolveExpressible(sessionFactory);
        if (!(sqmExpressible.getExpressibleJavaType() instanceof TemporalJavaType)) {
            throw new UnsupportedOperationException("Cannot treat non-temporal parameter type with temporal precision");
        }
        final TemporalJavaType<T> temporalJtd = (TemporalJavaType<T>) sqmExpressible.getExpressibleJavaType();
        if (temporalJtd.getPrecision() != precision) {
            final TypeConfiguration typeConfiguration = sessionFactory.getTypeConfiguration();
            return typeConfiguration.getBasicTypeRegistry().resolve(temporalJtd.resolveTypeForPrecision(precision, typeConfiguration), TemporalJavaType.resolveJdbcTypeCode(precision));
        }
    }
    return declaredParameterType;
}
Also used : TemporalJavaType(org.hibernate.type.descriptor.java.TemporalJavaType) TypeConfiguration(org.hibernate.type.spi.TypeConfiguration)

Aggregations

TemporalJavaType (org.hibernate.type.descriptor.java.TemporalJavaType)5 TemporalType (jakarta.persistence.TemporalType)2 MappingException (org.hibernate.MappingException)2 JdbcType (org.hibernate.type.descriptor.jdbc.JdbcType)2 ObjectJdbcType (org.hibernate.type.descriptor.jdbc.ObjectJdbcType)2 Serializable (java.io.Serializable)1 BasicValue (org.hibernate.mapping.BasicValue)1 Column (org.hibernate.mapping.Column)1 JdbcMapping (org.hibernate.metamodel.mapping.JdbcMapping)1 BasicAttributeMapping (org.hibernate.metamodel.mapping.internal.BasicAttributeMapping)1 MappingMetamodelImplementor (org.hibernate.metamodel.spi.MappingMetamodelImplementor)1 EntityPersister (org.hibernate.persister.entity.EntityPersister)1 SerializableType (org.hibernate.type.SerializableType)1 BasicJavaType (org.hibernate.type.descriptor.java.BasicJavaType)1 EnumJavaType (org.hibernate.type.descriptor.java.EnumJavaType)1 SerializableJavaType (org.hibernate.type.descriptor.java.SerializableJavaType)1 TypeConfiguration (org.hibernate.type.spi.TypeConfiguration)1 Test (org.junit.jupiter.api.Test)1