Skip to content

Commit

Permalink
HHH-17504 - Ongoing JPA 32 work
Browse files Browse the repository at this point in the history
HHH-17460 - Ongoing JPA 32 work
HHH-17350 - Work on hibernate-models, XSD and JAXB
HHH-16114 - Improve boot metamodel binding
HHH-15996 - Develop an abstraction for Annotation in annotation processing
HHH-16012 - Develop an abstraction for domain model Class refs
HHH-15997 - Support for dynamic models in orm.xml
HHH-15698 - Support for entity-name in mapping.xsd
  • Loading branch information
sebersole committed Mar 28, 2024
1 parent 5d4ad71 commit 1c5f0e2
Show file tree
Hide file tree
Showing 33 changed files with 358 additions and 321 deletions.
Expand Up @@ -57,6 +57,7 @@
import org.hibernate.loader.BatchFetchStyle;
import org.hibernate.proxy.EntityNotFoundDelegate;
import org.hibernate.query.ImmutableEntityUpdateQueryHandlingMode;
import org.hibernate.query.NullPrecedence;
import org.hibernate.query.criteria.ValueHandlingMode;
import org.hibernate.query.hql.HqlTranslator;
import org.hibernate.query.internal.NullPrecedenceHelper;
Expand Down Expand Up @@ -382,8 +383,11 @@ public SessionFactoryOptionsBuilder(StandardServiceRegistry serviceRegistry, Boo
this.maximumFetchDepth = getInteger( MAX_FETCH_DEPTH, configurationSettings );

final Object defaultNullPrecedence = configurationSettings.get( DEFAULT_NULL_ORDERING );
if ( defaultNullPrecedence instanceof NullPrecedence ) {
this.defaultNullPrecedence = (NullPrecedence) defaultNullPrecedence;
if ( defaultNullPrecedence instanceof Nulls jpaValue ) {
this.defaultNullPrecedence = jpaValue;
}
else if ( defaultNullPrecedence instanceof NullPrecedence hibernateValue ) {
this.defaultNullPrecedence = hibernateValue.getJpaValue();
}
else if ( defaultNullPrecedence instanceof String ) {
this.defaultNullPrecedence = NullPrecedenceHelper.parse( (String) defaultNullPrecedence );
Expand Down
Expand Up @@ -6,12 +6,35 @@
*/
package org.hibernate.boot.model.internal;

import java.lang.reflect.ParameterizedType;
import java.util.HashMap;
import java.util.List;

import org.hibernate.annotations.Parameter;
import org.hibernate.boot.model.convert.spi.ConverterDescriptor;
import org.hibernate.boot.spi.BootstrapContext;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.dialect.Dialect;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.models.spi.AnnotationUsage;
import org.hibernate.resource.beans.internal.FallbackBeanInstanceProducer;
import org.hibernate.resource.beans.spi.ManagedBean;
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
import org.hibernate.type.BasicType;
import org.hibernate.type.CustomType;
import org.hibernate.type.descriptor.converter.internal.JpaAttributeConverterImpl;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.spi.JavaTypeRegistry;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators;
import org.hibernate.type.internal.ConvertedBasicTypeImpl;
import org.hibernate.type.spi.TypeConfiguration;
import org.hibernate.usertype.UserType;

import jakarta.persistence.AttributeConverter;

import static org.hibernate.internal.util.GenericsHelper.extractClass;
import static org.hibernate.internal.util.GenericsHelper.extractParameterizedType;
import static org.hibernate.internal.util.collections.CollectionHelper.mapOfSize;

/**
Expand All @@ -25,4 +48,121 @@ public static HashMap<String, String> extractParameterMap(List<AnnotationUsage<P
} );
return paramMap;
}

public static JdbcMapping resolveUserType(Class<UserType<?>> userTypeClass, MetadataBuildingContext context) {
final BootstrapContext bootstrapContext = context.getBootstrapContext();
final UserType<?> userType = !context.getBuildingOptions().isAllowExtensionsInCdi()
? FallbackBeanInstanceProducer.INSTANCE.produceBeanInstance( userTypeClass )
: bootstrapContext.getServiceRegistry().requireService( ManagedBeanRegistry.class ).getBean( userTypeClass ).getBeanInstance();
return new CustomType<>( userType, bootstrapContext.getTypeConfiguration() );
}

public static JdbcMapping resolveAttributeConverter(Class<AttributeConverter<?, ?>> type, MetadataBuildingContext context) {
final BootstrapContext bootstrapContext = context.getBootstrapContext();
final ManagedBean<AttributeConverter<?, ?>> bean = bootstrapContext.getServiceRegistry()
.requireService( ManagedBeanRegistry.class )
.getBean( type );

final TypeConfiguration typeConfiguration = bootstrapContext.getTypeConfiguration();
final JavaTypeRegistry jtdRegistry = typeConfiguration.getJavaTypeRegistry();

final ParameterizedType converterParameterizedType = extractParameterizedType( bean.getBeanClass() );
final Class<?> domainJavaClass = extractClass( converterParameterizedType.getActualTypeArguments()[0] );
final Class<?> relationalJavaClass = extractClass( converterParameterizedType.getActualTypeArguments()[1] );

final JavaType<?> domainJtd = jtdRegistry.resolveDescriptor( domainJavaClass );
final JavaType<?> relationalJtd = jtdRegistry.resolveDescriptor( relationalJavaClass );

final JavaType<? extends AttributeConverter<?,?>> converterJtd =
jtdRegistry.resolveDescriptor( bean.getBeanClass() );
@SuppressWarnings({"rawtypes", "unchecked"})
final JpaAttributeConverterImpl<?,?> valueConverter =
new JpaAttributeConverterImpl( bean, converterJtd, domainJtd, relationalJtd );
return new ConvertedBasicTypeImpl<>(
ConverterDescriptor.TYPE_NAME_PREFIX
+ valueConverter.getConverterJavaType().getTypeName(),
String.format(
"BasicType adapter for AttributeConverter<%s,%s>",
domainJtd.getTypeName(),
relationalJtd.getTypeName()
),
relationalJtd.getRecommendedJdbcType( typeConfiguration.getCurrentBaseSqlTypeIndicators() ),
valueConverter
);
}

public static BasicType<Object> resolveBasicType(Class<?> type, MetadataBuildingContext context) {
final TypeConfiguration typeConfiguration = context.getBootstrapContext().getTypeConfiguration();
final JavaType<Object> jtd = typeConfiguration.getJavaTypeRegistry().findDescriptor( type );
if ( jtd != null ) {
final JdbcType jdbcType = jtd.getRecommendedJdbcType(
new JdbcTypeIndicators() {
@Override
public TypeConfiguration getTypeConfiguration() {
return typeConfiguration;
}

@Override
public int getPreferredSqlTypeCodeForBoolean() {
return context.getPreferredSqlTypeCodeForBoolean();
}

@Override
public int getPreferredSqlTypeCodeForDuration() {
return context.getPreferredSqlTypeCodeForDuration();
}

@Override
public int getPreferredSqlTypeCodeForUuid() {
return context.getPreferredSqlTypeCodeForUuid();
}

@Override
public int getPreferredSqlTypeCodeForInstant() {
return context.getPreferredSqlTypeCodeForInstant();
}

@Override
public int getPreferredSqlTypeCodeForArray() {
return context.getPreferredSqlTypeCodeForArray();
}

@Override
public Dialect getDialect() {
return context.getMetadataCollector().getDatabase().getDialect();
}
}
);
return typeConfiguration.getBasicTypeRegistry().resolve( jtd, jdbcType );
}
else {
return null;
}
}

public static JdbcMapping resolveJavaType(Class<JavaType<?>> type, MetadataBuildingContext context) {
final TypeConfiguration typeConfiguration = context.getBootstrapContext().getTypeConfiguration();
final JavaType<?> jtd = getJavaType( type, context, typeConfiguration );
final JdbcType jdbcType = jtd.getRecommendedJdbcType( typeConfiguration.getCurrentBaseSqlTypeIndicators() );
return typeConfiguration.getBasicTypeRegistry().resolve( jtd, jdbcType );
}

private static JavaType<?> getJavaType(
Class<JavaType<?>> javaTypeClass,
MetadataBuildingContext context,
TypeConfiguration typeConfiguration) {
final JavaType<?> registeredJtd = typeConfiguration.getJavaTypeRegistry().findDescriptor( javaTypeClass );
if ( registeredJtd != null ) {
return registeredJtd;
}
else if ( !context.getBuildingOptions().isAllowExtensionsInCdi() ) {
return FallbackBeanInstanceProducer.INSTANCE.produceBeanInstance( javaTypeClass );
}
else {
return context.getBootstrapContext().getServiceRegistry()
.requireService( ManagedBeanRegistry.class )
.getBean( javaTypeClass )
.getBeanInstance();
}
}
}
Expand Up @@ -124,7 +124,7 @@ private static void bindAny(
binder.setCascade( cascadeStrategy );
binder.setBuildingContext( context );
binder.setHolder( propertyHolder );
binder.setProperty( property );
binder.setMemberDetails( property );
binder.setEntityBinder( entityBinder );
Property prop = binder.makeProperty();
prop.setOptional( optional && value.isNullable() );
Expand Down
Expand Up @@ -6,7 +6,6 @@
*/
package org.hibernate.boot.model.internal;

import java.lang.reflect.ParameterizedType;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
Expand All @@ -17,46 +16,47 @@
import org.hibernate.annotations.FilterDef;
import org.hibernate.annotations.FilterDefs;
import org.hibernate.annotations.ParamDef;
import org.hibernate.boot.model.convert.spi.ConverterDescriptor;
import org.hibernate.boot.spi.BootstrapContext;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.FilterDefinition;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.models.spi.AnnotationTarget;
import org.hibernate.models.spi.AnnotationUsage;
import org.hibernate.models.spi.ClassDetails;
import org.hibernate.resource.beans.internal.FallbackBeanInstanceProducer;
import org.hibernate.resource.beans.spi.ManagedBean;
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
import org.hibernate.type.BasicType;
import org.hibernate.type.CustomType;
import org.hibernate.type.descriptor.converter.internal.JpaAttributeConverterImpl;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.spi.JavaTypeRegistry;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators;
import org.hibernate.type.internal.ConvertedBasicTypeImpl;
import org.hibernate.type.spi.TypeConfiguration;
import org.hibernate.usertype.UserType;

import jakarta.persistence.AttributeConverter;
import java.util.function.Supplier;

import static java.util.Collections.emptyMap;
import static org.hibernate.boot.model.internal.AnnotationHelper.resolveAttributeConverter;
import static org.hibernate.boot.model.internal.AnnotationHelper.resolveBasicType;
import static org.hibernate.boot.model.internal.AnnotationHelper.resolveJavaType;
import static org.hibernate.boot.model.internal.AnnotationHelper.resolveUserType;
import static org.hibernate.boot.model.internal.BinderHelper.getOverridableAnnotation;
import static org.hibernate.internal.CoreLogging.messageLogger;
import static org.hibernate.internal.util.GenericsHelper.extractClass;
import static org.hibernate.internal.util.GenericsHelper.extractParameterizedType;

/**
* @author Gavin King
*/
class FilterDefBinder {

private static final CoreMessageLogger LOG = messageLogger( FilterDefBinder.class );

public static void bindFilterDefs(AnnotationTarget annotatedElement, MetadataBuildingContext context) {
final AnnotationUsage<FilterDef> filterDef = annotatedElement.getAnnotationUsage( FilterDef.class );
final AnnotationUsage<FilterDefs> filterDefs = getOverridableAnnotation( annotatedElement, FilterDefs.class, context );
if ( filterDef != null ) {
bindFilterDef( filterDef, context );
}
if ( filterDefs != null ) {
final List<AnnotationUsage<FilterDef>> nestedDefs = filterDefs.getList( "value" );
for ( AnnotationUsage<FilterDef> def : nestedDefs ) {
bindFilterDef( def, context );
}
}
}

public static void bindFilterDef(AnnotationUsage<FilterDef> filterDef, MetadataBuildingContext context) {
final String name = filterDef.getString( "name" );
if ( context.getMetadataCollector().getFilterDefinition( name ) != null ) {
Expand Down Expand Up @@ -130,137 +130,4 @@ else if ( JavaType.class.isAssignableFrom( type ) ) {
return resolveBasicType( type, context );
}
}

private static BasicType<Object> resolveBasicType(Class<?> type, MetadataBuildingContext context) {
final TypeConfiguration typeConfiguration = context.getBootstrapContext().getTypeConfiguration();
final JavaType<Object> jtd = typeConfiguration.getJavaTypeRegistry().findDescriptor( type );
if ( jtd != null ) {
final JdbcType jdbcType = jtd.getRecommendedJdbcType(
new JdbcTypeIndicators() {
@Override
public TypeConfiguration getTypeConfiguration() {
return typeConfiguration;
}

@Override
public int getPreferredSqlTypeCodeForBoolean() {
return context.getPreferredSqlTypeCodeForBoolean();
}

@Override
public int getPreferredSqlTypeCodeForDuration() {
return context.getPreferredSqlTypeCodeForDuration();
}

@Override
public int getPreferredSqlTypeCodeForUuid() {
return context.getPreferredSqlTypeCodeForUuid();
}

@Override
public int getPreferredSqlTypeCodeForInstant() {
return context.getPreferredSqlTypeCodeForInstant();
}

@Override
public int getPreferredSqlTypeCodeForArray() {
return context.getPreferredSqlTypeCodeForArray();
}

@Override
public Dialect getDialect() {
return context.getMetadataCollector().getDatabase().getDialect();
}
}
);
return typeConfiguration.getBasicTypeRegistry().resolve( jtd, jdbcType );
}
else {
return null;
}
}

private static JdbcMapping resolveUserType(Class<UserType<?>> userTypeClass, MetadataBuildingContext context) {
final BootstrapContext bootstrapContext = context.getBootstrapContext();
final UserType<?> userType =
!context.getBuildingOptions().isAllowExtensionsInCdi()
? FallbackBeanInstanceProducer.INSTANCE.produceBeanInstance( userTypeClass )
: bootstrapContext.getServiceRegistry().requireService( ManagedBeanRegistry.class )
.getBean( userTypeClass ).getBeanInstance();
return new CustomType<>( userType, bootstrapContext.getTypeConfiguration() );
}

private static JdbcMapping resolveAttributeConverter(Class<AttributeConverter<?, ?>> type, MetadataBuildingContext context) {
final BootstrapContext bootstrapContext = context.getBootstrapContext();
final ManagedBean<AttributeConverter<?, ?>> bean =
bootstrapContext.getServiceRegistry()
.requireService( ManagedBeanRegistry.class )
.getBean( type );

final TypeConfiguration typeConfiguration = bootstrapContext.getTypeConfiguration();
final JavaTypeRegistry jtdRegistry = typeConfiguration.getJavaTypeRegistry();

final ParameterizedType converterParameterizedType = extractParameterizedType( bean.getBeanClass() );
final Class<?> domainJavaClass = extractClass( converterParameterizedType.getActualTypeArguments()[0] );
final Class<?> relationalJavaClass = extractClass( converterParameterizedType.getActualTypeArguments()[1] );

final JavaType<?> domainJtd = jtdRegistry.resolveDescriptor( domainJavaClass );
final JavaType<?> relationalJtd = jtdRegistry.resolveDescriptor( relationalJavaClass );

final JavaType<? extends AttributeConverter<?,?>> converterJtd =
jtdRegistry.resolveDescriptor( bean.getBeanClass() );
@SuppressWarnings({"rawtypes", "unchecked"})
final JpaAttributeConverterImpl<?,?> valueConverter =
new JpaAttributeConverterImpl( bean, converterJtd, domainJtd, relationalJtd );
return new ConvertedBasicTypeImpl<>(
ConverterDescriptor.TYPE_NAME_PREFIX
+ valueConverter.getConverterJavaType().getTypeName(),
String.format(
"BasicType adapter for AttributeConverter<%s,%s>",
domainJtd.getTypeName(),
relationalJtd.getTypeName()
),
relationalJtd.getRecommendedJdbcType( typeConfiguration.getCurrentBaseSqlTypeIndicators() ),
valueConverter
);
}

private static JdbcMapping resolveJavaType(Class<JavaType<?>> type, MetadataBuildingContext context) {
final TypeConfiguration typeConfiguration = context.getBootstrapContext().getTypeConfiguration();
final JavaType<?> jtd = getJavaType( type, context, typeConfiguration );
final JdbcType jdbcType = jtd.getRecommendedJdbcType( typeConfiguration.getCurrentBaseSqlTypeIndicators() );
return typeConfiguration.getBasicTypeRegistry().resolve( jtd, jdbcType );
}

private static JavaType<?> getJavaType(Class<JavaType<?>> javaTypeClass,
MetadataBuildingContext context,
TypeConfiguration typeConfiguration) {
final JavaType<?> registeredJtd = typeConfiguration.getJavaTypeRegistry().findDescriptor( javaTypeClass );
if ( registeredJtd != null ) {
return registeredJtd;
}
else if ( !context.getBuildingOptions().isAllowExtensionsInCdi() ) {
return FallbackBeanInstanceProducer.INSTANCE.produceBeanInstance( javaTypeClass );
}
else {
return context.getBootstrapContext().getServiceRegistry()
.requireService( ManagedBeanRegistry.class )
.getBean( javaTypeClass )
.getBeanInstance();
}
}

public static void bindFilterDefs(AnnotationTarget annotatedElement, MetadataBuildingContext context) {
final AnnotationUsage<FilterDef> filterDef = annotatedElement.getAnnotationUsage( FilterDef.class );
final AnnotationUsage<FilterDefs> filterDefs = getOverridableAnnotation( annotatedElement, FilterDefs.class, context );
if ( filterDef != null ) {
bindFilterDef( filterDef, context );
}
if ( filterDefs != null ) {
final List<AnnotationUsage<FilterDef>> nestedDefs = filterDefs.getList( "value" );
for ( AnnotationUsage<FilterDef> def : nestedDefs ) {
bindFilterDef( def, context );
}
}
}
}

0 comments on commit 1c5f0e2

Please sign in to comment.