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);
}
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;
};
}
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);
}
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();
}
}
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());
};
}
}
Aggregations