HHH-18106 - Java constant field resolution moved to JpaMetamodel

This commit is contained in:
Cedomir Igaly 2024-05-14 17:02:34 +02:00 committed by Gavin King
parent 8d2a0047e0
commit d738e75662
4 changed files with 58 additions and 10 deletions

View File

@ -19,6 +19,7 @@ import org.hibernate.jpa.spi.JpaCompliance;
import org.hibernate.metamodel.MappingMetamodel; import org.hibernate.metamodel.MappingMetamodel;
import org.hibernate.service.ServiceRegistry; import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.descriptor.java.EnumJavaType; import org.hibernate.type.descriptor.java.EnumJavaType;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.spi.TypeConfiguration; import org.hibernate.type.spi.TypeConfiguration;
/** /**
@ -94,6 +95,10 @@ public interface JpaMetamodel extends Metamodel {
<E extends Enum<E>> E enumValue(EnumJavaType<E> enumType, String terminal); <E extends Enum<E>> E enumValue(EnumJavaType<E> enumType, String terminal);
JavaType<?> getJavaConstantType(String className, String fieldName);
<T> T getJavaConstant(String className, String fieldName);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Covariant returns // Covariant returns

View File

@ -8,6 +8,7 @@ package org.hibernate.metamodel.model.domain.internal;
import java.io.ObjectStreamException; import java.io.ObjectStreamException;
import java.io.Serializable; import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@ -319,6 +320,43 @@ public class JpaMetamodelImpl implements JpaMetamodelImplementor, Serializable {
return Enum.valueOf( enumType.getJavaTypeClass(), terminal ); return Enum.valueOf( enumType.getJavaTypeClass(), terminal );
} }
@Override
public JavaType<?> getJavaConstantType(String className, String fieldName) {
try {
final Field referencedField = getJavaField( className, fieldName );
if ( referencedField != null ) {
return getTypeConfiguration()
.getJavaTypeRegistry()
.getDescriptor( referencedField.getType() );
}
}
catch (NoSuchFieldException e) {
}
return null;
}
@Override
public <T> T getJavaConstant(String className, String fieldName) {
try {
final Field referencedField = getJavaField( className, fieldName );
return (T) referencedField.get( null );
}
catch (NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException( e );
}
}
private Field getJavaField(String className, String fieldName) throws NoSuchFieldException {
final Class<?> namedClass =
getServiceRegistry()
.requireService( ClassLoaderService.class )
.classForName( className );
if ( namedClass != null ) {
return namedClass.getDeclaredField( fieldName );
}
return null;
}
@Override @Override
public <T> void addNamedEntityGraph(String graphName, RootGraphImplementor<T> entityGraph) { public <T> void addNamedEntityGraph(String graphName, RootGraphImplementor<T> entityGraph) {
final EntityGraph<?> old = entityGraphMap.put( final EntityGraph<?> old = entityGraphMap.put(

View File

@ -534,6 +534,16 @@ public class MappingMetamodelImpl extends QueryParameterBindingTypeResolverImpl
return jpaMetamodel.getAllowedEnumLiteralTexts(enumValue); return jpaMetamodel.getAllowedEnumLiteralTexts(enumValue);
} }
@Override
public JavaType<?> getJavaConstantType(String className, String fieldName) {
return jpaMetamodel.getJavaConstantType( className, fieldName );
}
@Override
public <T> T getJavaConstant(String className, String fieldName) {
return jpaMetamodel.getJavaConstant( className, fieldName );
}
@Override @Override
public EnumJavaType<?> getEnumType(String className) { public EnumJavaType<?> getEnumType(String className) {
return jpaMetamodel.getEnumType(className); return jpaMetamodel.getEnumType(className);

View File

@ -228,16 +228,11 @@ public class BasicDotIdentifierConsumer implements DotIdentifierConsumer {
); );
} }
final Class<?> namedClass = final JavaType<?> fieldJtdTest = jpaMetamodel.getJavaConstantType( prefix, terminal );
creationContext.getServiceRegistry() if ( fieldJtdTest != null ) {
.requireService( ClassLoaderService.class ) final Object constantValue = jpaMetamodel.getJavaConstant( prefix, terminal );
.classForName( prefix ); return new SqmFieldLiteral( constantValue, fieldJtdTest, terminal, nodeBuilder );
if ( namedClass != null ) {
final Field referencedField = namedClass.getDeclaredField( terminal );
final JavaType<?> fieldJtd =
jpaMetamodel.getTypeConfiguration().getJavaTypeRegistry()
.getDescriptor( referencedField.getType() );
return new SqmFieldLiteral<>( referencedField, fieldJtd, nodeBuilder);
} }
} }
catch (Exception ignore) { catch (Exception ignore) {