Skip to content

HHH-19466 continue cleaning up JpaMetamodel SPI #10265

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jun 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions hibernate-core/src/main/java/org/hibernate/SessionFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -506,8 +506,8 @@ default <T> RootGraph<T> createEntityGraph(Class<T> entityType) {
RootGraph<Map<String,?>> createGraphForDynamicEntity(String entityName);

/**
* Creates a RootGraph for the given {@code rootEntityClass} and parses the graph text into
* it.
* Creates a {@link RootGraph} for the given {@code rootEntityClass} and parses the
* graph text into it.
*
* @param rootEntityClass The entity class to use as the base of the created root-graph
* @param graphText The textual representation of the graph
Expand All @@ -527,8 +527,8 @@ default <T> RootGraph<T> parseEntityGraph(Class<T> rootEntityClass, CharSequence
}

/**
* Creates a RootGraph for the given {@code rootEntityName} and parses the graph text into
* it.
* Creates a {@link RootGraph} for the given {@code rootEntityName} and parses the graph
* text into it.
*
* @param rootEntityName The name of the entity to use as the base of the created root-graph
* @param graphText The textual representation of the graph
Expand All @@ -548,7 +548,7 @@ default <T> RootGraph<T> parseEntityGraph(String rootEntityName, CharSequence gr
}

/**
* Creates a RootGraph based on the passed string representation. Here, the
* Creates a {@link RootGraph} based on the passed string representation. Here, the
* string representation is expected to include the root entity name.
*
* @param graphText The textual representation of the graph
Expand All @@ -565,7 +565,7 @@ default <T> RootGraph<T> parseEntityGraph(CharSequence graphText) {
}

/**
* Obtain the set of names of all {@link org.hibernate.annotations.FilterDef
* Obtain the set of names of all {@linkplain org.hibernate.annotations.FilterDef
* defined filters}.
*
* @return The set of filter names given by
Expand All @@ -588,7 +588,7 @@ default <T> RootGraph<T> parseEntityGraph(CharSequence graphText) {
FilterDefinition getFilterDefinition(String filterName) throws HibernateException;

/**
* Obtain the set of names of all {@link org.hibernate.annotations.FetchProfile
* Obtain the set of names of all {@linkplain org.hibernate.annotations.FetchProfile
* defined fetch profiles}.
*
* @return The set of fetch profile names given by
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -641,9 +641,9 @@ public SqlStringGenerationContext getSqlStringGenerationContext() {
return sqlStringGenerationContext;
}

@Override @SuppressWarnings({"rawtypes","unchecked"})
@Override
public <T> List<EntityGraph<? super T>> findEntityGraphsByType(Class<T> entityClass) {
return (List) getJpaMetamodel().findEntityGraphsByJavaType( entityClass );
return getJpaMetamodel().findEntityGraphsByJavaType( entityClass );
}

// todo : (5.2) review synchronizationType, persistenceContextType, transactionType usage
Expand Down Expand Up @@ -928,7 +928,7 @@ public <T> T unwrap(Class<T> type) {

@Override
public <T> void addNamedEntityGraph(String graphName, EntityGraph<T> entityGraph) {
getMappingMetamodel().addNamedEntityGraph( graphName, (RootGraphImplementor<T>) entityGraph );
getJpaMetamodel().addNamedEntityGraph( graphName, (RootGraphImplementor<T>) entityGraph );
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,14 @@
*/
package org.hibernate.metamodel;

import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Stream;

import org.hibernate.Incubating;
import org.hibernate.Internal;
import org.hibernate.graph.RootGraph;
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
import org.hibernate.metamodel.mapping.MappingModelExpressible;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.NavigableRole;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
Expand Down Expand Up @@ -164,22 +161,6 @@ public interface MappingMetamodel extends Metamodel {
*/
CollectionPersister findCollectionDescriptor(String role);


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// JPA entity graphs

RootGraph<?> findNamedGraph(String name);
void addNamedEntityGraph(String graphName, RootGraph<?> entityGraph);
void forEachNamedGraph(Consumer<RootGraph<?>> action);
RootGraph<?> defaultGraph(String entityName);
RootGraph<?> defaultGraph(Class<?> entityJavaType);
RootGraph<?> defaultGraph(EntityPersister entityDescriptor);
RootGraph<?> defaultGraph(EntityDomainType<?> entityDomainType);

List<RootGraph<?>> findRootGraphsForType(Class<?> baseEntityJavaType);
List<RootGraph<?>> findRootGraphsForType(String baseEntityName);
List<RootGraph<?>> findRootGraphsForType(EntityPersister baseEntityDescriptor);

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// SQM model -> Mapping model

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,26 @@
import org.hibernate.boot.query.NamedQueryDefinition;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
import org.hibernate.metamodel.model.domain.spi.JpaMetamodelImplementor;

import java.lang.reflect.Field;

import static java.lang.Character.charCount;
import static java.lang.Character.isJavaIdentifierPart;

public class InjectionHelper {
private static final CoreMessageLogger log = CoreLogging.messageLogger( MetadataContext.class );

public static void injectEntityGraph(
NamedEntityGraphDefinition definition,
Class<?> metamodelClass,
JpaMetamodel jpaMetamodel) {
JpaMetamodelImplementor jpaMetamodel) {
if ( metamodelClass != null ) {
final String name = definition.name();
final String fieldName = '_' + javaIdentifier( name );
final var graph = jpaMetamodel.findEntityGraphByName( name );
try {
injectField(
metamodelClass,
'_' + javaIdentifier( definition.name() ),
jpaMetamodel.findEntityGraphByName( definition.name() ),
false
);
injectField( metamodelClass, fieldName, graph, false );
}
catch ( NoSuchFieldException e ) {
// ignore
Expand All @@ -40,13 +38,10 @@ public static void injectEntityGraph(

public static void injectTypedQueryReference(NamedQueryDefinition<?> definition, Class<?> metamodelClass) {
if ( metamodelClass != null ) {
final String fieldName =
'_' + javaIdentifier( definition.getRegistrationName() ) + '_';
try {
injectField(
metamodelClass,
'_' + javaIdentifier( definition.getRegistrationName() ) + '_',
definition,
false
);
injectField( metamodelClass, fieldName, definition, false );
}
catch ( NoSuchFieldException e ) {
// ignore
Expand All @@ -59,12 +54,7 @@ public static String javaIdentifier(String name) {
int position = 0;
while ( position < name.length() ) {
final int codePoint = name.codePointAt( position );
if ( Character.isJavaIdentifierPart(codePoint) ) {
result.appendCodePoint( codePoint );
}
else {
result.append('_');
}
result.appendCodePoint( isJavaIdentifierPart( codePoint ) ? codePoint : '_' );
position += charCount( codePoint );
}
return result.toString();
Expand All @@ -74,12 +64,13 @@ public static void injectField(
Class<?> metamodelClass, String name, Object model,
boolean allowNonDeclaredFieldReference)
throws NoSuchFieldException {
final Field field = allowNonDeclaredFieldReference
? metamodelClass.getField(name)
: metamodelClass.getDeclaredField(name);
final Field field =
allowNonDeclaredFieldReference
? metamodelClass.getField( name )
: metamodelClass.getDeclaredField( name );
try {
// should be public anyway, but to be sure...
ReflectHelper.ensureAccessibility( field );
// ReflectHelper.ensureAccessibility( field );
field.set( null, model);
}
catch (IllegalAccessException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ public static JpaMetamodelPopulationSetting parse(String setting) {
};
}

public static JpaMetamodelPopulationSetting determineJpaMetaModelPopulationSetting(Map configurationValues) {
public static JpaMetamodelPopulationSetting determineJpaMetaModelPopulationSetting(Map<String, Object> settings) {
String setting = ConfigurationHelper.getString(
AvailableSettings.JPA_METAMODEL_POPULATION,
configurationValues,
settings,
"ignoreUnsupported"
);
return JpaMetamodelPopulationSetting.parse( setting );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* <p>
* Encapsulates a {@link JavaType} describing the more rudimentary aspects
* of the Java type. The {@code DomainType} is a higher-level construct
* incorporating information such as bean properties, constructors, etc.
* incorporating information such as bean properties, constructors, and so on.
*
* @implNote The actual JPA type system is more akin to {@link SimpleDomainType}.
* This contract represents a "higher level" abstraction, allowing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,12 @@
*/
package org.hibernate.metamodel.model.domain;

import java.util.List;
import java.util.Map;
import java.util.Set;

import jakarta.persistence.EntityGraph;

import jakarta.persistence.metamodel.Metamodel;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.hibernate.Incubating;
import org.hibernate.graph.RootGraph;
import org.hibernate.metamodel.MappingMetamodel;
import org.hibernate.type.descriptor.java.EnumJavaType;
import org.hibernate.type.descriptor.java.JavaType;
Expand Down Expand Up @@ -100,6 +96,9 @@ public interface JpaMetamodel extends Metamodel {

String qualifyImportableName(String queryName);

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Enumerations and Java constants (useful for interpreting HQL)

@Nullable Set<String> getEnumTypesForValue(String enumValue);

EnumJavaType<?> getEnumType(String className);
Expand All @@ -122,15 +121,4 @@ public interface JpaMetamodel extends Metamodel {
@Override
<X> EmbeddableDomainType<X> embeddable(Class<X> cls);


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Entity graphs

void addNamedEntityGraph(String graphName, RootGraph<?> entityGraph);

RootGraph<?> findEntityGraphByName(String name);

<T> List<RootGraph<? super T>> findEntityGraphsByJavaType(Class<T> entityClass);

<T> Map<String, EntityGraph<? extends T>> getNamedEntityGraphs(Class<T> entityType);
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.graph.RootGraph;
import org.hibernate.graph.spi.RootGraphImplementor;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
Expand Down Expand Up @@ -355,8 +354,7 @@ public JavaType<?> getJavaConstantType(String className, String fieldName) {
try {
final Field referencedField = getJavaField( className, fieldName );
if ( referencedField != null ) {
return getTypeConfiguration()
.getJavaTypeRegistry()
return getTypeConfiguration().getJavaTypeRegistry()
.getDescriptor( referencedField.getType() );
}
}
Expand Down Expand Up @@ -387,11 +385,10 @@ private Field getJavaField(String className, String fieldName) throws NoSuchFiel
}

@Override
public void addNamedEntityGraph(String graphName, RootGraph<?> entityGraph) {
final RootGraphImplementor<?> rootGraph = (RootGraphImplementor<?>) entityGraph;
public void addNamedEntityGraph(String graphName, RootGraphImplementor<?> rootGraph) {
final EntityGraph<?> old = entityGraphMap.put( graphName, rootGraph.makeImmutableCopy( graphName ) );
if ( old != null ) {
log.debugf( "EntityGraph being replaced on EntityManagerFactory for name %s", graphName );
log.debugf( "EntityGraph named '%s' was replaced", graphName );
}
}

Expand All @@ -401,13 +398,13 @@ public RootGraphImplementor<?> findEntityGraphByName(String name) {
}

@Override
public <T> List<RootGraph<? super T>> findEntityGraphsByJavaType(Class<T> entityClass) {
public <T> List<EntityGraph<? super T>> findEntityGraphsByJavaType(Class<T> entityClass) {
final EntityDomainType<T> entityType = entity( entityClass );
if ( entityType == null ) {
throw new IllegalArgumentException( "Given class is not an entity: " + entityClass.getName() );
}
else {
final List<RootGraph<? super T>> results = new ArrayList<>();
final List<EntityGraph<? super T>> results = new ArrayList<>();
for ( var entityGraph : entityGraphMap.values() ) {
if ( entityGraph.appliesTo( entityType ) ) {
@SuppressWarnings("unchecked") // safe, we just checked
Expand Down
Loading
Loading