Search in sources :

Example 1 with BasicJavaType

use of org.hibernate.type.descriptor.java.BasicJavaType 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 BasicJavaType

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

the class BasicValueBinder method prepareMapKey.

private void prepareMapKey(XProperty mapAttribute, XClass modelPropertyTypeXClass) {
    final XClass mapKeyClass;
    if (modelPropertyTypeXClass == null) {
        mapKeyClass = mapAttribute.getMapKey();
    } else {
        mapKeyClass = modelPropertyTypeXClass;
    }
    final Class<?> implicitJavaType = resolveJavaType(mapKeyClass);
    implicitJavaTypeAccess = (typeConfiguration) -> implicitJavaType;
    final MapKeyEnumerated mapKeyEnumeratedAnn = mapAttribute.getAnnotation(MapKeyEnumerated.class);
    if (mapKeyEnumeratedAnn != null) {
        enumType = mapKeyEnumeratedAnn.value();
    }
    final MapKeyTemporal mapKeyTemporalAnn = mapAttribute.getAnnotation(MapKeyTemporal.class);
    if (mapKeyTemporalAnn != null) {
        temporalPrecision = mapKeyTemporalAnn.value();
    }
    explicitJdbcTypeAccess = typeConfiguration -> {
        final MapKeyJdbcType jdbcTypeAnn = findAnnotation(mapAttribute, MapKeyJdbcType.class);
        if (jdbcTypeAnn != null) {
            final Class<? extends JdbcType> jdbcTypeImpl = normalizeJdbcType(jdbcTypeAnn.value());
            if (jdbcTypeImpl != null) {
                return getManagedBeanRegistry().getBean(jdbcTypeImpl).getBeanInstance();
            }
        }
        final MapKeyJdbcTypeCode jdbcTypeCodeAnn = findAnnotation(mapAttribute, MapKeyJdbcTypeCode.class);
        if (jdbcTypeCodeAnn != null) {
            final int jdbcTypeCode = jdbcTypeCodeAnn.value();
            if (jdbcTypeCode != Integer.MIN_VALUE) {
                return typeConfiguration.getJdbcTypeRegistry().getDescriptor(jdbcTypeCode);
            }
        }
        return null;
    };
    explicitJavaTypeAccess = typeConfiguration -> {
        final MapKeyJavaType javaTypeAnn = findAnnotation(mapAttribute, MapKeyJavaType.class);
        if (javaTypeAnn != null) {
            final Class<? extends BasicJavaType<?>> jdbcTypeImpl = normalizeJavaType(javaTypeAnn.value());
            if (jdbcTypeImpl != null) {
                final ManagedBean<? extends BasicJavaType> jdbcTypeBean = getManagedBeanRegistry().getBean(jdbcTypeImpl);
                return jdbcTypeBean.getBeanInstance();
            }
        }
        final MapKeyClass mapKeyClassAnn = mapAttribute.getAnnotation(MapKeyClass.class);
        if (mapKeyClassAnn != null) {
            return (BasicJavaType<?>) typeConfiguration.getJavaTypeRegistry().getDescriptor(mapKeyClassAnn.value());
        }
        return null;
    };
    explicitMutabilityAccess = typeConfiguration -> {
        final MapKeyMutability mutabilityAnn = findAnnotation(mapAttribute, MapKeyMutability.class);
        if (mutabilityAnn != null) {
            final Class<? extends MutabilityPlan<?>> mutability = normalizeMutability(mutabilityAnn.value());
            if (mutability != null) {
                final ManagedBean<? extends MutabilityPlan<?>> jtdBean = getManagedBeanRegistry().getBean(mutability);
                return jtdBean.getBeanInstance();
            }
        }
        // see if the value's type Class is annotated `@Immutable`
        if (implicitJavaTypeAccess != null) {
            final Class<?> attributeType = ReflectHelper.getClass(implicitJavaTypeAccess.apply(typeConfiguration));
            if (attributeType != null) {
                if (attributeType.isAnnotationPresent(Immutable.class)) {
                    return ImmutableMutabilityPlan.instance();
                }
            }
        }
        // if the value is converted, see if the converter Class is annotated `@Immutable`
        if (converterDescriptor != null) {
            final Mutability converterMutabilityAnn = converterDescriptor.getAttributeConverterClass().getAnnotation(Mutability.class);
            if (converterMutabilityAnn != null) {
                final ManagedBean<? extends MutabilityPlan<?>> jtdBean = getManagedBeanRegistry().getBean(converterMutabilityAnn.value());
                return jtdBean.getBeanInstance();
            }
            if (converterDescriptor.getAttributeConverterClass().isAnnotationPresent(Immutable.class)) {
                return ImmutableMutabilityPlan.instance();
            }
        }
        final Class<? extends UserType> customTypeImpl = Kind.MAP_KEY.mappingAccess.customType(mapAttribute);
        if (customTypeImpl != null) {
            if (customTypeImpl.isAnnotationPresent(Immutable.class)) {
                return ImmutableMutabilityPlan.instance();
            }
        }
        // generally, this will trigger usage of the `JavaType#getMutabilityPlan`
        return null;
    };
}
Also used : MapKeyJdbcTypeCode(org.hibernate.annotations.MapKeyJdbcTypeCode) Mutability(org.hibernate.annotations.Mutability) CollectionIdMutability(org.hibernate.annotations.CollectionIdMutability) MapKeyMutability(org.hibernate.annotations.MapKeyMutability) MapKeyJavaType(org.hibernate.annotations.MapKeyJavaType) XClass(org.hibernate.annotations.common.reflection.XClass) MapKeyEnumerated(jakarta.persistence.MapKeyEnumerated) MapKeyClass(jakarta.persistence.MapKeyClass) BasicJavaType(org.hibernate.type.descriptor.java.BasicJavaType) MapKeyMutability(org.hibernate.annotations.MapKeyMutability) MapKeyTemporal(jakarta.persistence.MapKeyTemporal) MapKeyJdbcType(org.hibernate.annotations.MapKeyJdbcType)

Example 3 with BasicJavaType

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

the class VersionResolution method from.

// todo (6.0) : support explicit JTD?
// todo (6.0) : support explicit STD?
@SuppressWarnings({ "rawtypes", "unchecked" })
public static <E> VersionResolution<E> from(Function<TypeConfiguration, java.lang.reflect.Type> implicitJavaTypeAccess, Function<TypeConfiguration, BasicJavaType> explicitJtdAccess, Function<TypeConfiguration, JdbcType> explicitStdAccess, TimeZoneStorageType timeZoneStorageType, TypeConfiguration typeConfiguration, @SuppressWarnings("unused") MetadataBuildingContext context) {
    // todo (6.0) : add support for Dialect-specific interpretation?
    final java.lang.reflect.Type implicitJavaType = implicitJavaTypeAccess.apply(typeConfiguration);
    final JavaType registered = typeConfiguration.getJavaTypeRegistry().resolveDescriptor(implicitJavaType);
    final BasicJavaType jtd = (BasicJavaType) registered;
    final JdbcType recommendedJdbcType = jtd.getRecommendedJdbcType(new JdbcTypeIndicators() {

        @Override
        public TypeConfiguration getTypeConfiguration() {
            return typeConfiguration;
        }

        @Override
        public TemporalType getTemporalPrecision() {
            // if it is a temporal version, it needs to be a TIMESTAMP
            return TemporalType.TIMESTAMP;
        }

        @Override
        public TimeZoneStorageStrategy getDefaultTimeZoneStorageStrategy() {
            if (timeZoneStorageType != null) {
                switch(timeZoneStorageType) {
                    case NATIVE:
                        return TimeZoneStorageStrategy.NATIVE;
                    case NORMALIZE:
                        return TimeZoneStorageStrategy.NORMALIZE;
                }
            }
            return context.getBuildingOptions().getDefaultTimeZoneStorage();
        }
    });
    final BasicType<?> basicType = typeConfiguration.getBasicTypeRegistry().resolve(jtd, recommendedJdbcType);
    final BasicType legacyType = typeConfiguration.getBasicTypeRegistry().getRegisteredType(jtd.getJavaType());
    assert legacyType.getJdbcType().equals(recommendedJdbcType);
    return new VersionResolution<>(jtd, recommendedJdbcType, basicType, legacyType);
}
Also used : JdbcTypeIndicators(org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators) TimeZoneStorageStrategy(org.hibernate.TimeZoneStorageStrategy) BasicType(org.hibernate.type.BasicType) JdbcType(org.hibernate.type.descriptor.jdbc.JdbcType) BasicJavaType(org.hibernate.type.descriptor.java.BasicJavaType) JavaType(org.hibernate.type.descriptor.java.JavaType) BasicJavaType(org.hibernate.type.descriptor.java.BasicJavaType) TypeConfiguration(org.hibernate.type.spi.TypeConfiguration) TemporalType(jakarta.persistence.TemporalType)

Example 4 with BasicJavaType

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

the class BasicValueBinder method normalSupplementalDetails.

private void normalSupplementalDetails(XProperty attributeXProperty) {
    explicitJavaTypeAccess = typeConfiguration -> {
        final org.hibernate.annotations.JavaType javaTypeAnn = findAnnotation(attributeXProperty, org.hibernate.annotations.JavaType.class);
        if (javaTypeAnn != null) {
            final Class<? extends BasicJavaType<?>> javaType = normalizeJavaType(javaTypeAnn.value());
            if (javaType != null) {
                final ManagedBean<? extends BasicJavaType<?>> jtdBean = getManagedBeanRegistry().getBean(javaType);
                return jtdBean.getBeanInstance();
            }
        }
        final Target targetAnn = findAnnotation(attributeXProperty, Target.class);
        if (targetAnn != null) {
            return (BasicJavaType<?>) typeConfiguration.getJavaTypeRegistry().getDescriptor(targetAnn.value());
        }
        return null;
    };
    normalJdbcTypeDetails(attributeXProperty);
    normalMutabilityDetails(attributeXProperty);
    final Enumerated enumeratedAnn = attributeXProperty.getAnnotation(Enumerated.class);
    if (enumeratedAnn != null) {
        enumType = enumeratedAnn.value();
    }
    final Temporal temporalAnn = attributeXProperty.getAnnotation(Temporal.class);
    if (temporalAnn != null) {
        temporalPrecision = temporalAnn.value();
    }
}
Also used : MapKeyEnumerated(jakarta.persistence.MapKeyEnumerated) Enumerated(jakarta.persistence.Enumerated) Target(org.hibernate.annotations.Target) BasicJavaType(org.hibernate.type.descriptor.java.BasicJavaType) Temporal(jakarta.persistence.Temporal) MapKeyTemporal(jakarta.persistence.MapKeyTemporal)

Example 5 with BasicJavaType

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

the class BasicValueBinder method prepareCollectionElement.

private void prepareCollectionElement(XProperty attributeXProperty, XClass elementTypeXClass) {
    XClass xclass = elementTypeXClass == null && attributeXProperty.isArray() ? attributeXProperty.getElementClass() : elementTypeXClass;
    Class<?> javaType = resolveJavaType(xclass);
    implicitJavaTypeAccess = typeConfiguration -> javaType;
    final Temporal temporalAnn = attributeXProperty.getAnnotation(Temporal.class);
    if (temporalAnn != null) {
        temporalPrecision = temporalAnn.value();
        if (temporalPrecision == null) {
            throw new IllegalStateException("No jakarta.persistence.TemporalType defined for @jakarta.persistence.Temporal " + "associated with attribute " + attributeXProperty.getDeclaringClass().getName() + '.' + attributeXProperty.getName());
        }
    } else {
        temporalPrecision = null;
    }
    if (javaType.isEnum()) {
        final Enumerated enumeratedAnn = attributeXProperty.getAnnotation(Enumerated.class);
        if (enumeratedAnn != null) {
            enumType = enumeratedAnn.value();
            if (enumType == null) {
                throw new IllegalStateException("jakarta.persistence.EnumType was null on @jakarta.persistence.Enumerated " + " associated with attribute " + attributeXProperty.getDeclaringClass().getName() + '.' + attributeXProperty.getName());
            }
        }
    } else {
        enumType = null;
    }
    final TimeZoneStorage timeZoneStorageAnn = attributeXProperty.getAnnotation(TimeZoneStorage.class);
    timeZoneStorageType = timeZoneStorageAnn != null ? timeZoneStorageAnn.value() : null;
    normalSupplementalDetails(attributeXProperty);
    // layer in support for JPA's approach for specifying a specific Java type for the collection elements...
    final ElementCollection elementCollectionAnn = attributeXProperty.getAnnotation(ElementCollection.class);
    if (elementCollectionAnn != null && elementCollectionAnn.targetClass() != null && elementCollectionAnn.targetClass() != void.class) {
        final Function<TypeConfiguration, BasicJavaType> original = explicitJavaTypeAccess;
        explicitJavaTypeAccess = (typeConfiguration) -> {
            final BasicJavaType<?> originalResult = original.apply(typeConfiguration);
            if (originalResult != null) {
                return originalResult;
            }
            return (BasicJavaType<?>) typeConfiguration.getJavaTypeRegistry().getDescriptor(elementCollectionAnn.targetClass());
        };
    }
}
Also used : MapKeyEnumerated(jakarta.persistence.MapKeyEnumerated) Enumerated(jakarta.persistence.Enumerated) BasicJavaType(org.hibernate.type.descriptor.java.BasicJavaType) Temporal(jakarta.persistence.Temporal) MapKeyTemporal(jakarta.persistence.MapKeyTemporal) ElementCollection(jakarta.persistence.ElementCollection) TypeConfiguration(org.hibernate.type.spi.TypeConfiguration) XClass(org.hibernate.annotations.common.reflection.XClass) TimeZoneStorage(org.hibernate.annotations.TimeZoneStorage)

Aggregations

BasicJavaType (org.hibernate.type.descriptor.java.BasicJavaType)10 JdbcType (org.hibernate.type.descriptor.jdbc.JdbcType)5 MapKeyEnumerated (jakarta.persistence.MapKeyEnumerated)3 MapKeyTemporal (jakarta.persistence.MapKeyTemporal)3 Enumerated (jakarta.persistence.Enumerated)2 Temporal (jakarta.persistence.Temporal)2 MappingException (org.hibernate.MappingException)2 XClass (org.hibernate.annotations.common.reflection.XClass)2 BasicValue (org.hibernate.mapping.BasicValue)2 EnumJavaType (org.hibernate.type.descriptor.java.EnumJavaType)2 TypeConfiguration (org.hibernate.type.spi.TypeConfiguration)2 ElementCollection (jakarta.persistence.ElementCollection)1 MapKeyClass (jakarta.persistence.MapKeyClass)1 TemporalType (jakarta.persistence.TemporalType)1 Serializable (java.io.Serializable)1 BigInteger (java.math.BigInteger)1 Properties (java.util.Properties)1 HibernateException (org.hibernate.HibernateException)1 TimeZoneStorageStrategy (org.hibernate.TimeZoneStorageStrategy)1 AnyKeyJavaClass (org.hibernate.annotations.AnyKeyJavaClass)1