HHH-18649 populate EntityGraph in static metamodel
This commit is contained in:
parent
c863838e72
commit
600288d1bb
|
@ -42,7 +42,8 @@ public class NamedHqlQueryDefinitionImpl<E> extends AbstractNamedQueryDefinition
|
||||||
Integer fetchSize,
|
Integer fetchSize,
|
||||||
String comment,
|
String comment,
|
||||||
Map<String,String> parameterTypes,
|
Map<String,String> parameterTypes,
|
||||||
Map<String,Object> hints) {
|
Map<String,Object> hints,
|
||||||
|
String location) {
|
||||||
super(
|
super(
|
||||||
name,
|
name,
|
||||||
resultType,
|
resultType,
|
||||||
|
@ -55,7 +56,8 @@ public class NamedHqlQueryDefinitionImpl<E> extends AbstractNamedQueryDefinition
|
||||||
timeout,
|
timeout,
|
||||||
fetchSize,
|
fetchSize,
|
||||||
comment,
|
comment,
|
||||||
hints
|
hints,
|
||||||
|
location
|
||||||
);
|
);
|
||||||
this.hqlString = hqlString;
|
this.hqlString = hqlString;
|
||||||
this.firstResult = firstResult;
|
this.firstResult = firstResult;
|
||||||
|
|
|
@ -44,7 +44,8 @@ public class NamedNativeQueryDefinitionImpl<E> extends AbstractNamedQueryDefinit
|
||||||
String comment,
|
String comment,
|
||||||
Integer firstResult,
|
Integer firstResult,
|
||||||
Integer maxResults,
|
Integer maxResults,
|
||||||
Map<String,Object> hints) {
|
Map<String,Object> hints,
|
||||||
|
String location) {
|
||||||
super(
|
super(
|
||||||
name,
|
name,
|
||||||
resultType,
|
resultType,
|
||||||
|
@ -57,7 +58,8 @@ public class NamedNativeQueryDefinitionImpl<E> extends AbstractNamedQueryDefinit
|
||||||
timeout,
|
timeout,
|
||||||
fetchSize,
|
fetchSize,
|
||||||
comment,
|
comment,
|
||||||
hints
|
hints,
|
||||||
|
location
|
||||||
);
|
);
|
||||||
this.sqlString = sqlString;
|
this.sqlString = sqlString;
|
||||||
this.resultSetMappingName = resultSetMappingName;
|
this.resultSetMappingName = resultSetMappingName;
|
||||||
|
|
|
@ -10,6 +10,7 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import org.hibernate.CacheMode;
|
import org.hibernate.CacheMode;
|
||||||
import org.hibernate.FlushMode;
|
import org.hibernate.FlushMode;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
|
@ -74,6 +75,12 @@ public class NamedProcedureCallDefinitionImpl implements NamedProcedureCallDefin
|
||||||
return registeredName;
|
return registeredName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable String getLocation() {
|
||||||
|
// not kept for now
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getProcedureName() {
|
public String getProcedureName() {
|
||||||
return procedureName;
|
return procedureName;
|
||||||
|
|
|
@ -104,11 +104,11 @@ public final class AnnotationBinder {
|
||||||
// queries ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// queries ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
globalRegistrations.getNamedQueryRegistrations().forEach( (name, queryRegistration) -> {
|
globalRegistrations.getNamedQueryRegistrations().forEach( (name, queryRegistration) -> {
|
||||||
QueryBinder.bindQuery( queryRegistration.configuration(), context, true );
|
QueryBinder.bindQuery( queryRegistration.configuration(), context, true, null );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
globalRegistrations.getNamedNativeQueryRegistrations().forEach( (name, queryRegistration) -> {
|
globalRegistrations.getNamedNativeQueryRegistrations().forEach( (name, queryRegistration) -> {
|
||||||
QueryBinder.bindNativeQuery( queryRegistration.configuration(), context, true );
|
QueryBinder.bindNativeQuery( queryRegistration.configuration(), context, null, true );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
globalRegistrations.getNamedStoredProcedureQueryRegistrations().forEach( (name, queryRegistration) -> {
|
globalRegistrations.getNamedStoredProcedureQueryRegistrations().forEach( (name, queryRegistration) -> {
|
||||||
|
@ -152,13 +152,13 @@ public final class AnnotationBinder {
|
||||||
annotationTarget.forEachRepeatedAnnotationUsages(
|
annotationTarget.forEachRepeatedAnnotationUsages(
|
||||||
HibernateAnnotations.NAMED_QUERY,
|
HibernateAnnotations.NAMED_QUERY,
|
||||||
sourceModelContext,
|
sourceModelContext,
|
||||||
(usage) -> QueryBinder.bindQuery( usage, context )
|
(usage) -> QueryBinder.bindQuery( usage, context, annotationTarget )
|
||||||
);
|
);
|
||||||
|
|
||||||
annotationTarget.forEachRepeatedAnnotationUsages(
|
annotationTarget.forEachRepeatedAnnotationUsages(
|
||||||
HibernateAnnotations.NAMED_NATIVE_QUERY,
|
HibernateAnnotations.NAMED_NATIVE_QUERY,
|
||||||
sourceModelContext,
|
sourceModelContext,
|
||||||
(usage) -> QueryBinder.bindNativeQuery( usage, context )
|
(usage) -> QueryBinder.bindNativeQuery( usage, context, annotationTarget )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,13 +174,13 @@ public final class AnnotationBinder {
|
||||||
annotationTarget.forEachRepeatedAnnotationUsages(
|
annotationTarget.forEachRepeatedAnnotationUsages(
|
||||||
JpaAnnotations.NAMED_QUERY,
|
JpaAnnotations.NAMED_QUERY,
|
||||||
sourceModelContext,
|
sourceModelContext,
|
||||||
(usage) -> QueryBinder.bindQuery( usage, context, false )
|
(usage) -> QueryBinder.bindQuery( usage, context, false, annotationTarget )
|
||||||
);
|
);
|
||||||
|
|
||||||
annotationTarget.forEachRepeatedAnnotationUsages(
|
annotationTarget.forEachRepeatedAnnotationUsages(
|
||||||
JpaAnnotations.NAMED_NATIVE_QUERY,
|
JpaAnnotations.NAMED_NATIVE_QUERY,
|
||||||
sourceModelContext,
|
sourceModelContext,
|
||||||
(usage) -> QueryBinder.bindNativeQuery( usage, context, false )
|
(usage) -> QueryBinder.bindNativeQuery( usage, context, annotationTarget, false )
|
||||||
);
|
);
|
||||||
|
|
||||||
annotationTarget.forEachRepeatedAnnotationUsages(
|
annotationTarget.forEachRepeatedAnnotationUsages(
|
||||||
|
|
|
@ -14,6 +14,7 @@ import java.util.function.Supplier;
|
||||||
import org.hibernate.AnnotationException;
|
import org.hibernate.AnnotationException;
|
||||||
import org.hibernate.CacheMode;
|
import org.hibernate.CacheMode;
|
||||||
import org.hibernate.FlushMode;
|
import org.hibernate.FlushMode;
|
||||||
|
import org.hibernate.models.spi.AnnotationTarget;
|
||||||
import org.hibernate.query.QueryFlushMode;
|
import org.hibernate.query.QueryFlushMode;
|
||||||
import org.hibernate.LockOptions;
|
import org.hibernate.LockOptions;
|
||||||
import org.hibernate.annotations.FlushModeType;
|
import org.hibernate.annotations.FlushModeType;
|
||||||
|
@ -74,7 +75,8 @@ public abstract class QueryBinder {
|
||||||
public static void bindQuery(
|
public static void bindQuery(
|
||||||
NamedQuery namedQuery,
|
NamedQuery namedQuery,
|
||||||
MetadataBuildingContext context,
|
MetadataBuildingContext context,
|
||||||
boolean isDefault) {
|
boolean isDefault,
|
||||||
|
AnnotationTarget annotationTarget) {
|
||||||
if ( namedQuery == null ) {
|
if ( namedQuery == null ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -94,7 +96,7 @@ public abstract class QueryBinder {
|
||||||
final QueryHintDefinition hints = new QueryHintDefinition( queryName, namedQuery.hints() );
|
final QueryHintDefinition hints = new QueryHintDefinition( queryName, namedQuery.hints() );
|
||||||
final NamedHqlQueryDefinition<?> queryMapping =
|
final NamedHqlQueryDefinition<?> queryMapping =
|
||||||
createNamedQueryDefinition( queryName, queryString, resultClass,
|
createNamedQueryDefinition( queryName, queryString, resultClass,
|
||||||
hints.determineLockOptions( namedQuery ), hints );
|
hints.determineLockOptions( namedQuery ), hints, annotationTarget );
|
||||||
if ( isDefault ) {
|
if ( isDefault ) {
|
||||||
context.getMetadataCollector().addDefaultQuery( queryMapping );
|
context.getMetadataCollector().addDefaultQuery( queryMapping );
|
||||||
}
|
}
|
||||||
|
@ -105,8 +107,8 @@ public abstract class QueryBinder {
|
||||||
|
|
||||||
private static <T> NamedHqlQueryDefinitionImpl<T> createNamedQueryDefinition(
|
private static <T> NamedHqlQueryDefinitionImpl<T> createNamedQueryDefinition(
|
||||||
String queryName, String queryString, Class<T> resultClass, LockOptions lockOptions,
|
String queryName, String queryString, Class<T> resultClass, LockOptions lockOptions,
|
||||||
QueryHintDefinition hints) {
|
QueryHintDefinition hints, AnnotationTarget annotationTarget) {
|
||||||
return new NamedHqlQueryDefinitionImpl.Builder<T>(queryName)
|
return new NamedHqlQueryDefinitionImpl.Builder<T>(queryName, annotationTarget)
|
||||||
.setHqlString(queryString)
|
.setHqlString(queryString)
|
||||||
.setResultClass(resultClass)
|
.setResultClass(resultClass)
|
||||||
.setCacheable(hints.getCacheability())
|
.setCacheable(hints.getCacheability())
|
||||||
|
@ -124,6 +126,7 @@ public abstract class QueryBinder {
|
||||||
public static void bindNativeQuery(
|
public static void bindNativeQuery(
|
||||||
NamedNativeQuery namedNativeQuery,
|
NamedNativeQuery namedNativeQuery,
|
||||||
MetadataBuildingContext context,
|
MetadataBuildingContext context,
|
||||||
|
AnnotationTarget location,
|
||||||
boolean isDefault) {
|
boolean isDefault) {
|
||||||
if ( namedNativeQuery == null ) {
|
if ( namedNativeQuery == null ) {
|
||||||
return;
|
return;
|
||||||
|
@ -143,7 +146,7 @@ public abstract class QueryBinder {
|
||||||
final Class<?> resultClass = void.class == resultClassDetails ? null : resultClassDetails;
|
final Class<?> resultClass = void.class == resultClassDetails ? null : resultClassDetails;
|
||||||
|
|
||||||
final NamedNativeQueryDefinition<?> queryDefinition =
|
final NamedNativeQueryDefinition<?> queryDefinition =
|
||||||
createNamedQueryDefinition( registrationName, queryString, resultClass, resultSetMappingName, hints );
|
createNamedQueryDefinition( registrationName, queryString, resultClass, resultSetMappingName, hints, location );
|
||||||
|
|
||||||
if ( LOG.isDebugEnabled() ) {
|
if ( LOG.isDebugEnabled() ) {
|
||||||
LOG.debugf( "Binding named native query: %s => %s",
|
LOG.debugf( "Binding named native query: %s => %s",
|
||||||
|
@ -161,8 +164,9 @@ public abstract class QueryBinder {
|
||||||
private static <T> NamedNativeQueryDefinition<T> createNamedQueryDefinition(
|
private static <T> NamedNativeQueryDefinition<T> createNamedQueryDefinition(
|
||||||
String registrationName, String queryString,
|
String registrationName, String queryString,
|
||||||
Class<T> resultClass, String resultSetMappingName,
|
Class<T> resultClass, String resultSetMappingName,
|
||||||
QueryHintDefinition hints) {
|
QueryHintDefinition hints,
|
||||||
return new NamedNativeQueryDefinition.Builder<T>(registrationName)
|
AnnotationTarget location) {
|
||||||
|
return new NamedNativeQueryDefinition.Builder<T>(registrationName, location)
|
||||||
.setSqlString(queryString)
|
.setSqlString(queryString)
|
||||||
.setResultClass(resultClass)
|
.setResultClass(resultClass)
|
||||||
.setResultSetMappingName(resultSetMappingName)
|
.setResultSetMappingName(resultSetMappingName)
|
||||||
|
@ -184,7 +188,8 @@ public abstract class QueryBinder {
|
||||||
SQLSelect sqlSelect,
|
SQLSelect sqlSelect,
|
||||||
ClassDetails annotatedClass,
|
ClassDetails annotatedClass,
|
||||||
MetadataBuildingContext context) {
|
MetadataBuildingContext context) {
|
||||||
final NamedNativeQueryDefinition.Builder<?> builder = new NamedNativeQueryDefinition.Builder<>( name )
|
final NamedNativeQueryDefinition.Builder<?> builder =
|
||||||
|
new NamedNativeQueryDefinition.Builder<>( name )
|
||||||
.setFlushMode( FlushMode.MANUAL )
|
.setFlushMode( FlushMode.MANUAL )
|
||||||
.setSqlString( sqlSelect.sql() )
|
.setSqlString( sqlSelect.sql() )
|
||||||
.setQuerySpaces( setOf( sqlSelect.querySpaces() ) );
|
.setQuerySpaces( setOf( sqlSelect.querySpaces() ) );
|
||||||
|
@ -210,7 +215,8 @@ public abstract class QueryBinder {
|
||||||
|
|
||||||
public static void bindNativeQuery(
|
public static void bindNativeQuery(
|
||||||
org.hibernate.annotations.NamedNativeQuery namedNativeQuery,
|
org.hibernate.annotations.NamedNativeQuery namedNativeQuery,
|
||||||
MetadataBuildingContext context) {
|
MetadataBuildingContext context,
|
||||||
|
AnnotationTarget location) {
|
||||||
if ( namedNativeQuery == null ) {
|
if ( namedNativeQuery == null ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -231,7 +237,7 @@ public abstract class QueryBinder {
|
||||||
|
|
||||||
final NamedNativeQueryDefinition.Builder<?> builder =
|
final NamedNativeQueryDefinition.Builder<?> builder =
|
||||||
createQueryDefinition( namedNativeQuery, registrationName, resultSetMappingName, resultClass,
|
createQueryDefinition( namedNativeQuery, registrationName, resultSetMappingName, resultClass,
|
||||||
namedNativeQuery.timeout(), namedNativeQuery.fetchSize(), querySpaces );
|
namedNativeQuery.timeout(), namedNativeQuery.fetchSize(), querySpaces, location );
|
||||||
|
|
||||||
if ( TRUE == namedNativeQuery.callable() ) {
|
if ( TRUE == namedNativeQuery.callable() ) {
|
||||||
final NamedProcedureCallDefinition definition =
|
final NamedProcedureCallDefinition definition =
|
||||||
|
@ -261,8 +267,9 @@ public abstract class QueryBinder {
|
||||||
String registrationName, String resultSetMappingName,
|
String registrationName, String resultSetMappingName,
|
||||||
Class<T> resultClass,
|
Class<T> resultClass,
|
||||||
int timeout, int fetchSize,
|
int timeout, int fetchSize,
|
||||||
HashSet<String> querySpaces) {
|
HashSet<String> querySpaces,
|
||||||
return new NamedNativeQueryDefinition.Builder<T>(registrationName)
|
AnnotationTarget location) {
|
||||||
|
return new NamedNativeQueryDefinition.Builder<T>(registrationName, location)
|
||||||
.setSqlString(namedNativeQuery.query())
|
.setSqlString(namedNativeQuery.query())
|
||||||
.setResultSetMappingName(resultSetMappingName)
|
.setResultSetMappingName(resultSetMappingName)
|
||||||
.setResultClass(resultClass)
|
.setResultClass(resultClass)
|
||||||
|
@ -365,17 +372,18 @@ public abstract class QueryBinder {
|
||||||
String name,
|
String name,
|
||||||
HQLSelect hqlSelect,
|
HQLSelect hqlSelect,
|
||||||
MetadataBuildingContext context) {
|
MetadataBuildingContext context) {
|
||||||
final NamedHqlQueryDefinition<?> hqlQueryDefinition = new NamedHqlQueryDefinition.Builder<>( name )
|
final NamedHqlQueryDefinition<?> hqlQueryDefinition =
|
||||||
|
new NamedHqlQueryDefinition.Builder<>( name )
|
||||||
.setFlushMode( FlushMode.MANUAL )
|
.setFlushMode( FlushMode.MANUAL )
|
||||||
.setHqlString( hqlSelect.query() )
|
.setHqlString( hqlSelect.query() )
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
context.getMetadataCollector().addNamedQuery( hqlQueryDefinition );
|
context.getMetadataCollector().addNamedQuery( hqlQueryDefinition );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void bindQuery(
|
public static void bindQuery(
|
||||||
org.hibernate.annotations.NamedQuery namedQuery,
|
org.hibernate.annotations.NamedQuery namedQuery,
|
||||||
MetadataBuildingContext context) {
|
MetadataBuildingContext context,
|
||||||
|
AnnotationTarget location) {
|
||||||
if ( namedQuery == null ) {
|
if ( namedQuery == null ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -389,7 +397,7 @@ public abstract class QueryBinder {
|
||||||
|
|
||||||
final NamedHqlQueryDefinition.Builder<?> builder =
|
final NamedHqlQueryDefinition.Builder<?> builder =
|
||||||
createQueryDefinition( namedQuery, registrationName, resultClass,
|
createQueryDefinition( namedQuery, registrationName, resultClass,
|
||||||
namedQuery.timeout(), namedQuery.fetchSize() ) ;
|
namedQuery.timeout(), namedQuery.fetchSize(), location ) ;
|
||||||
|
|
||||||
final NamedHqlQueryDefinitionImpl<?> hqlQueryDefinition = builder.build();
|
final NamedHqlQueryDefinitionImpl<?> hqlQueryDefinition = builder.build();
|
||||||
|
|
||||||
|
@ -403,8 +411,9 @@ public abstract class QueryBinder {
|
||||||
|
|
||||||
private static <T> NamedHqlQueryDefinition.Builder<T> createQueryDefinition(
|
private static <T> NamedHqlQueryDefinition.Builder<T> createQueryDefinition(
|
||||||
org.hibernate.annotations.NamedQuery namedQuery,
|
org.hibernate.annotations.NamedQuery namedQuery,
|
||||||
String registrationName, Class<T> resultClass, int timeout, int fetchSize) {
|
String registrationName, Class<T> resultClass, int timeout, int fetchSize,
|
||||||
return new NamedHqlQueryDefinition.Builder<T>(registrationName)
|
AnnotationTarget location) {
|
||||||
|
return new NamedHqlQueryDefinition.Builder<T>(registrationName, location)
|
||||||
.setHqlString(namedQuery.query())
|
.setHqlString(namedQuery.query())
|
||||||
.setResultClass(resultClass)
|
.setResultClass(resultClass)
|
||||||
.setCacheable(namedQuery.cacheable())
|
.setCacheable(namedQuery.cacheable())
|
||||||
|
|
|
@ -47,7 +47,8 @@ public class NamedQueryBinder {
|
||||||
String prefix) {
|
String prefix) {
|
||||||
final String registrationName = prefix + namedQueryBinding.getName();
|
final String registrationName = prefix + namedQueryBinding.getName();
|
||||||
|
|
||||||
final NamedHqlQueryDefinition.Builder<?> queryBuilder = new NamedHqlQueryDefinition.Builder<>( registrationName )
|
final NamedHqlQueryDefinition.Builder<?> queryBuilder =
|
||||||
|
new NamedHqlQueryDefinition.Builder<>( registrationName )
|
||||||
.setComment( namedQueryBinding.getComment() )
|
.setComment( namedQueryBinding.getComment() )
|
||||||
.setCacheable( namedQueryBinding.isCacheable() )
|
.setCacheable( namedQueryBinding.isCacheable() )
|
||||||
.setCacheMode( namedQueryBinding.getCacheMode() )
|
.setCacheMode( namedQueryBinding.getCacheMode() )
|
||||||
|
@ -109,7 +110,8 @@ public class NamedQueryBinder {
|
||||||
|
|
||||||
final String registrationName = prefix + namedQueryBinding.getName();
|
final String registrationName = prefix + namedQueryBinding.getName();
|
||||||
|
|
||||||
final NamedNativeQueryDefinition.Builder<?> builder = new NamedNativeQueryDefinition.Builder<>( registrationName )
|
final NamedNativeQueryDefinition.Builder<?> builder =
|
||||||
|
new NamedNativeQueryDefinition.Builder<>( registrationName )
|
||||||
.setComment( namedQueryBinding.getComment() )
|
.setComment( namedQueryBinding.getComment() )
|
||||||
.setCacheable( namedQueryBinding.isCacheable() )
|
.setCacheable( namedQueryBinding.isCacheable() )
|
||||||
.setCacheMode( namedQueryBinding.getCacheMode() )
|
.setCacheMode( namedQueryBinding.getCacheMode() )
|
||||||
|
@ -222,12 +224,10 @@ public class NamedQueryBinder {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( content instanceof JaxbHbmQueryParamType ) {
|
if ( content instanceof JaxbHbmQueryParamType paramTypeBinding ) {
|
||||||
final JaxbHbmQueryParamType paramTypeBinding = (JaxbHbmQueryParamType) content;
|
|
||||||
queryBuilder.addParameterTypeHint( paramTypeBinding.getName(), paramTypeBinding.getType() );
|
queryBuilder.addParameterTypeHint( paramTypeBinding.getName(), paramTypeBinding.getType() );
|
||||||
}
|
}
|
||||||
else if ( content instanceof JaxbHbmSynchronizeType ) {
|
else if ( content instanceof JaxbHbmSynchronizeType synchronizedSpace ) {
|
||||||
final JaxbHbmSynchronizeType synchronizedSpace = (JaxbHbmSynchronizeType) content;
|
|
||||||
queryBuilder.addSynchronizedQuerySpace( synchronizedSpace.getTable() );
|
queryBuilder.addSynchronizedQuerySpace( synchronizedSpace.getTable() );
|
||||||
}
|
}
|
||||||
else if ( content instanceof JaxbHbmNativeQueryScalarReturnType ) {
|
else if ( content instanceof JaxbHbmNativeQueryScalarReturnType ) {
|
||||||
|
|
|
@ -12,6 +12,7 @@ import org.hibernate.FlushMode;
|
||||||
import org.hibernate.LockOptions;
|
import org.hibernate.LockOptions;
|
||||||
|
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
import org.hibernate.models.spi.AnnotationTarget;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
|
@ -36,14 +37,21 @@ public abstract class AbstractNamedQueryBuilder<R, T extends AbstractNamedQueryB
|
||||||
|
|
||||||
private Map<String, Object> hints;
|
private Map<String, Object> hints;
|
||||||
|
|
||||||
public AbstractNamedQueryBuilder(String name) {
|
private final AnnotationTarget location;
|
||||||
|
|
||||||
|
public AbstractNamedQueryBuilder(String name, AnnotationTarget location) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
this.location = location;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AnnotationTarget getLocation() {
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract T getThis();
|
protected abstract T getThis();
|
||||||
|
|
||||||
public T setResultClass(Class<R> resultClass) {
|
public T setResultClass(Class<R> resultClass) {
|
||||||
|
|
|
@ -9,6 +9,7 @@ import java.util.Map;
|
||||||
|
|
||||||
import org.hibernate.boot.internal.NamedHqlQueryDefinitionImpl;
|
import org.hibernate.boot.internal.NamedHqlQueryDefinitionImpl;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.models.spi.AnnotationTarget;
|
||||||
import org.hibernate.query.sqm.spi.NamedSqmQueryMemento;
|
import org.hibernate.query.sqm.spi.NamedSqmQueryMemento;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,8 +36,12 @@ public interface NamedHqlQueryDefinition<E> extends NamedQueryDefinition<E> {
|
||||||
|
|
||||||
private Map<String,String> parameterTypes;
|
private Map<String,String> parameterTypes;
|
||||||
|
|
||||||
|
public Builder(String name, AnnotationTarget location) {
|
||||||
|
super( name, location );
|
||||||
|
}
|
||||||
|
|
||||||
public Builder(String name) {
|
public Builder(String name) {
|
||||||
super( name );
|
super( name, null );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -80,7 +85,9 @@ public interface NamedHqlQueryDefinition<E> extends NamedQueryDefinition<E> {
|
||||||
getFetchSize(),
|
getFetchSize(),
|
||||||
getComment(),
|
getComment(),
|
||||||
parameterTypes,
|
parameterTypes,
|
||||||
getHints()
|
getHints(),
|
||||||
|
//TODO: should this be location.asClassDetails().getClassName() ?
|
||||||
|
getLocation() == null ? null : getLocation().getName()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ import java.util.Set;
|
||||||
|
|
||||||
import org.hibernate.boot.internal.NamedNativeQueryDefinitionImpl;
|
import org.hibernate.boot.internal.NamedNativeQueryDefinitionImpl;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.models.spi.AnnotationTarget;
|
||||||
import org.hibernate.query.sql.spi.NamedNativeQueryMemento;
|
import org.hibernate.query.sql.spi.NamedNativeQueryMemento;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,8 +44,12 @@ public interface NamedNativeQueryDefinition<E> extends NamedQueryDefinition<E> {
|
||||||
private Integer firstResult;
|
private Integer firstResult;
|
||||||
private Integer maxResults;
|
private Integer maxResults;
|
||||||
|
|
||||||
|
public Builder(String name, AnnotationTarget location) {
|
||||||
|
super( name, location );
|
||||||
|
}
|
||||||
|
|
||||||
public Builder(String name) {
|
public Builder(String name) {
|
||||||
super( name );
|
super( name, null );
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder<E> setSqlString(String sqlString) {
|
public Builder<E> setSqlString(String sqlString) {
|
||||||
|
@ -79,7 +84,9 @@ public interface NamedNativeQueryDefinition<E> extends NamedQueryDefinition<E> {
|
||||||
getComment(),
|
getComment(),
|
||||||
firstResult,
|
firstResult,
|
||||||
maxResults,
|
maxResults,
|
||||||
getHints()
|
getHints(),
|
||||||
|
//TODO: should this be location.asClassDetails().getClassName() ?
|
||||||
|
getLocation() == null ? null : getLocation().getName()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ public interface NamedQueryDefinition<E> extends TypedQueryReference<E> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name under which the query is to be registered
|
* The name under which the query is to be registered.
|
||||||
*/
|
*/
|
||||||
String getRegistrationName();
|
String getRegistrationName();
|
||||||
|
|
||||||
|
@ -36,7 +36,14 @@ public interface NamedQueryDefinition<E> extends TypedQueryReference<E> {
|
||||||
Class<E> getResultType();
|
Class<E> getResultType();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolve the mapping definition into its run-time memento form
|
* Resolve the mapping definition into its run-time memento form.
|
||||||
*/
|
*/
|
||||||
NamedQueryMemento<E> resolve(SessionFactoryImplementor factory);
|
NamedQueryMemento<E> resolve(SessionFactoryImplementor factory);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The location at which the defining named query annotation occurs,
|
||||||
|
* usually a class or package name. Null for named queries declared
|
||||||
|
* in XML.
|
||||||
|
*/
|
||||||
|
@Nullable String getLocation();
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ public abstract class AbstractNamedQueryDefinition<R> implements NamedQueryDefin
|
||||||
private final String comment;
|
private final String comment;
|
||||||
|
|
||||||
private final Map<String,Object> hints;
|
private final Map<String,Object> hints;
|
||||||
|
private final String location;
|
||||||
|
|
||||||
public AbstractNamedQueryDefinition(
|
public AbstractNamedQueryDefinition(
|
||||||
String name,
|
String name,
|
||||||
|
@ -49,7 +50,8 @@ public abstract class AbstractNamedQueryDefinition<R> implements NamedQueryDefin
|
||||||
Integer timeout,
|
Integer timeout,
|
||||||
Integer fetchSize,
|
Integer fetchSize,
|
||||||
String comment,
|
String comment,
|
||||||
Map<String,Object> hints) {
|
Map<String,Object> hints,
|
||||||
|
String location) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.resultType = resultType;
|
this.resultType = resultType;
|
||||||
this.cacheable = cacheable;
|
this.cacheable = cacheable;
|
||||||
|
@ -62,6 +64,7 @@ public abstract class AbstractNamedQueryDefinition<R> implements NamedQueryDefin
|
||||||
this.fetchSize = fetchSize;
|
this.fetchSize = fetchSize;
|
||||||
this.comment = comment;
|
this.comment = comment;
|
||||||
this.hints = hints == null ? new HashMap<>() : new HashMap<>( hints );
|
this.hints = hints == null ? new HashMap<>() : new HashMap<>( hints );
|
||||||
|
this.location = location;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -69,6 +72,11 @@ public abstract class AbstractNamedQueryDefinition<R> implements NamedQueryDefin
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable String getLocation() {
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable Class<R> getResultType() {
|
public @Nullable Class<R> getResultType() {
|
||||||
return resultType;
|
return resultType;
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
* Copyright Red Hat Inc. and Hibernate Authors
|
||||||
|
*/
|
||||||
|
package org.hibernate.metamodel.internal;
|
||||||
|
|
||||||
|
import org.hibernate.AssertionFailure;
|
||||||
|
import org.hibernate.boot.model.NamedEntityGraphDefinition;
|
||||||
|
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 java.lang.reflect.Field;
|
||||||
|
|
||||||
|
import static java.lang.Character.charCount;
|
||||||
|
|
||||||
|
public class InjectionHelper {
|
||||||
|
private static final CoreMessageLogger log = CoreLogging.messageLogger( MetadataContext.class );
|
||||||
|
|
||||||
|
public static void injectEntityGraph(
|
||||||
|
NamedEntityGraphDefinition definition,
|
||||||
|
Class<?> metamodelClass,
|
||||||
|
JpaMetamodel jpaMetamodel) {
|
||||||
|
if ( metamodelClass != null ) {
|
||||||
|
try {
|
||||||
|
injectField(
|
||||||
|
metamodelClass,
|
||||||
|
'_' + javaIdentifier( definition.getRegisteredName() ),
|
||||||
|
jpaMetamodel.findEntityGraphByName( definition.getRegisteredName() ),
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
catch ( NoSuchFieldException e ) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void injectTypedQueryReference(NamedQueryDefinition<?> definition, Class<?> metamodelClass) {
|
||||||
|
if ( metamodelClass != null ) {
|
||||||
|
try {
|
||||||
|
injectField(
|
||||||
|
metamodelClass,
|
||||||
|
'_' + javaIdentifier( definition.getRegistrationName() ) + '_',
|
||||||
|
definition,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
catch ( NoSuchFieldException e ) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String javaIdentifier(String name) {
|
||||||
|
final StringBuilder result = new StringBuilder();
|
||||||
|
int position = 0;
|
||||||
|
while ( position < name.length() ) {
|
||||||
|
final int codePoint = name.codePointAt( position );
|
||||||
|
if ( Character.isJavaIdentifierPart(codePoint) ) {
|
||||||
|
result.appendCodePoint( codePoint );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result.append('_');
|
||||||
|
}
|
||||||
|
position += charCount( codePoint );
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void injectField(
|
||||||
|
Class<?> metamodelClass, String name, Object model,
|
||||||
|
boolean allowNonDeclaredFieldReference)
|
||||||
|
throws NoSuchFieldException {
|
||||||
|
final Field field = allowNonDeclaredFieldReference
|
||||||
|
? metamodelClass.getField(name)
|
||||||
|
: metamodelClass.getDeclaredField(name);
|
||||||
|
try {
|
||||||
|
// should be public anyway, but to be sure...
|
||||||
|
ReflectHelper.ensureAccessibility( field );
|
||||||
|
field.set( null, model);
|
||||||
|
}
|
||||||
|
catch (IllegalAccessException e) {
|
||||||
|
// todo : exception type?
|
||||||
|
throw new AssertionFailure(
|
||||||
|
"Unable to inject static metamodel attribute : " + metamodelClass.getName() + '#' + name,
|
||||||
|
e
|
||||||
|
);
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException e) {
|
||||||
|
// most likely a mismatch in the type we are injecting and the defined field; this represents a
|
||||||
|
// mismatch in how the annotation processor interpreted the attribute and how our metamodel
|
||||||
|
// and/or annotation binder did.
|
||||||
|
|
||||||
|
// This is particularly the case as arrays are not handled properly by the StaticMetamodel generator
|
||||||
|
|
||||||
|
// throw new AssertionFailure(
|
||||||
|
// "Illegal argument on static metamodel field injection : " + metamodelClass.getName() + '#' + name
|
||||||
|
// + "; expected type : " + attribute.getClass().getName()
|
||||||
|
// + "; encountered type : " + field.getType().getName()
|
||||||
|
// );
|
||||||
|
log.illegalArgumentOnStaticMetamodelFieldInjection(
|
||||||
|
metamodelClass.getName(),
|
||||||
|
name,
|
||||||
|
model.getClass().getName(),
|
||||||
|
field.getType().getName()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -4,25 +4,18 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.metamodel.internal;
|
package org.hibernate.metamodel.internal;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import jakarta.persistence.metamodel.Attribute;
|
||||||
import java.util.ArrayList;
|
import jakarta.persistence.metamodel.IdentifiableType;
|
||||||
import java.util.HashMap;
|
import jakarta.persistence.metamodel.SingularAttribute;
|
||||||
import java.util.HashSet;
|
import jakarta.persistence.metamodel.Type;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.BiFunction;
|
|
||||||
|
|
||||||
import org.hibernate.AssertionFailure;
|
import org.hibernate.AssertionFailure;
|
||||||
import org.hibernate.Internal;
|
import org.hibernate.Internal;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.boot.query.NamedQueryDefinition;
|
|
||||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||||
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
||||||
import org.hibernate.boot.spi.MetadataImplementor;
|
import org.hibernate.boot.spi.MetadataImplementor;
|
||||||
import org.hibernate.internal.CoreLogging;
|
import org.hibernate.internal.CoreLogging;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.internal.util.ReflectHelper;
|
|
||||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||||
import org.hibernate.mapping.Component;
|
import org.hibernate.mapping.Component;
|
||||||
import org.hibernate.mapping.MappedSuperclass;
|
import org.hibernate.mapping.MappedSuperclass;
|
||||||
|
@ -53,13 +46,16 @@ import org.hibernate.type.descriptor.java.spi.JavaTypeRegistry;
|
||||||
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||||
import org.hibernate.type.spi.TypeConfiguration;
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
import jakarta.persistence.metamodel.Attribute;
|
import java.util.ArrayList;
|
||||||
import jakarta.persistence.metamodel.IdentifiableType;
|
import java.util.HashMap;
|
||||||
import jakarta.persistence.metamodel.SingularAttribute;
|
import java.util.HashSet;
|
||||||
import jakarta.persistence.metamodel.Type;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
import static java.lang.Character.charCount;
|
|
||||||
import static java.util.Collections.unmodifiableMap;
|
import static java.util.Collections.unmodifiableMap;
|
||||||
|
import static org.hibernate.metamodel.internal.InjectionHelper.injectField;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -278,8 +274,9 @@ public class MetadataContext {
|
||||||
attribute = factoryFunction.apply( entityType, genericProperty );
|
attribute = factoryFunction.apply( entityType, genericProperty );
|
||||||
if ( !property.isGeneric() ) {
|
if ( !property.isGeneric() ) {
|
||||||
final PersistentAttribute<X, ?> concreteAttribute = factoryFunction.apply( entityType, property );
|
final PersistentAttribute<X, ?> concreteAttribute = factoryFunction.apply( entityType, property );
|
||||||
//noinspection unchecked
|
@SuppressWarnings("unchecked")
|
||||||
( (AttributeContainer<X>) entityType ).getInFlightAccess().addConcreteGenericAttribute( concreteAttribute );
|
final AttributeContainer<X> attributeContainer = (AttributeContainer<X>) entityType;
|
||||||
|
attributeContainer.getInFlightAccess().addConcreteGenericAttribute( concreteAttribute );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -324,18 +321,7 @@ public class MetadataContext {
|
||||||
// skip the version property, it was already handled previously.
|
// skip the version property, it was already handled previously.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final PersistentAttribute<Object, ?> attribute = buildAttribute(
|
buildAttribute( property, jpaMapping );
|
||||||
property,
|
|
||||||
jpaMapping,
|
|
||||||
attributeFactory::buildAttribute
|
|
||||||
);
|
|
||||||
if ( attribute != null ) {
|
|
||||||
addAttribute( jpaMapping, attribute );
|
|
||||||
if ( property.isNaturalIdentifier() ) {
|
|
||||||
( ( AttributeContainer<Object>) jpaMapping ).getInFlightAccess()
|
|
||||||
.applyNaturalIdAttribute( attribute );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
( (AttributeContainer<?>) jpaMapping ).getInFlightAccess().finishUp();
|
( (AttributeContainer<?>) jpaMapping ).getInFlightAccess().finishUp();
|
||||||
|
@ -364,21 +350,10 @@ public class MetadataContext {
|
||||||
// applyNaturalIdAttribute( safeMapping, jpaType );
|
// applyNaturalIdAttribute( safeMapping, jpaType );
|
||||||
|
|
||||||
for ( Property property : safeMapping.getDeclaredProperties() ) {
|
for ( Property property : safeMapping.getDeclaredProperties() ) {
|
||||||
if ( safeMapping.isVersioned() && property == safeMapping.getVersion() ) {
|
if ( !safeMapping.isVersioned()
|
||||||
// skip the version property, it was already handled previously.
|
// skip the version property, it was already handled previously.
|
||||||
continue;
|
|| property != safeMapping.getVersion() ) {
|
||||||
}
|
buildAttribute( property, jpaType );
|
||||||
final PersistentAttribute<Object, ?> attribute = buildAttribute(
|
|
||||||
property,
|
|
||||||
jpaType,
|
|
||||||
attributeFactory::buildAttribute
|
|
||||||
);
|
|
||||||
if ( attribute != null ) {
|
|
||||||
addAttribute( jpaType, attribute );
|
|
||||||
if ( property.isNaturalIdentifier() ) {
|
|
||||||
( ( AttributeContainer<Object>) jpaType ).getInFlightAccess()
|
|
||||||
.applyNaturalIdAttribute( attribute );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -411,22 +386,9 @@ public class MetadataContext {
|
||||||
for ( EmbeddableDomainType<?> embeddable : processingEmbeddables ) {
|
for ( EmbeddableDomainType<?> embeddable : processingEmbeddables ) {
|
||||||
final Component component = componentByEmbeddable.get( embeddable );
|
final Component component = componentByEmbeddable.get( embeddable );
|
||||||
for ( Property property : component.getProperties() ) {
|
for ( Property property : component.getProperties() ) {
|
||||||
if ( component.isPolymorphic() && !embeddable.getTypeName().equals( component.getPropertyDeclaringClass( property ) ) ) {
|
if ( !component.isPolymorphic()
|
||||||
continue;
|
|| embeddable.getTypeName().equals( component.getPropertyDeclaringClass( property ) ) ) {
|
||||||
}
|
addAttribute( embeddable, property, component );
|
||||||
final PersistentAttribute<Object, ?> attribute =
|
|
||||||
attributeFactory.buildAttribute( (ManagedDomainType<Object>) embeddable, property );
|
|
||||||
if ( attribute != null ) {
|
|
||||||
final Property superclassProperty = getMappedSuperclassProperty(
|
|
||||||
property.getName(),
|
|
||||||
component.getMappedSuperclass()
|
|
||||||
);
|
|
||||||
if ( superclassProperty != null && superclassProperty.isGeneric() ) {
|
|
||||||
( (AttributeContainer<Object>) embeddable ).getInFlightAccess().addConcreteGenericAttribute( attribute );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
addAttribute( embeddable, attribute );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,20 +406,52 @@ public class MetadataContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addAttribute(ManagedDomainType<?> type, PersistentAttribute<Object, ?> attribute) {
|
private <T> void addAttribute(EmbeddableDomainType<T> embeddable, Property property, Component component) {
|
||||||
//noinspection unchecked
|
final PersistentAttribute<T, ?> attribute =
|
||||||
AttributeContainer<Object> container = (AttributeContainer<Object>) type;
|
attributeFactory.buildAttribute( embeddable, property);
|
||||||
final AttributeContainer.InFlightAccess<Object> inFlightAccess = container.getInFlightAccess();
|
if ( attribute != null ) {
|
||||||
|
final Property superclassProperty = getMappedSuperclassProperty(
|
||||||
|
property.getName(),
|
||||||
|
component.getMappedSuperclass()
|
||||||
|
);
|
||||||
|
if ( superclassProperty != null && superclassProperty.isGeneric() ) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
final AttributeContainer<T> attributeContainer = (AttributeContainer<T>) embeddable;
|
||||||
|
attributeContainer.getInFlightAccess().addConcreteGenericAttribute( attribute );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
addAttribute(embeddable, attribute );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> void buildAttribute(Property property, IdentifiableDomainType<T> jpaType) {
|
||||||
|
final PersistentAttribute<T, ?> attribute =
|
||||||
|
buildAttribute( property, jpaType, attributeFactory::buildAttribute );
|
||||||
|
if ( attribute != null ) {
|
||||||
|
addAttribute(jpaType, attribute );
|
||||||
|
if ( property.isNaturalIdentifier() ) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
final AttributeContainer<T> attributeContainer = (AttributeContainer<T>) jpaType;
|
||||||
|
attributeContainer.getInFlightAccess().applyNaturalIdAttribute( attribute );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> void addAttribute(ManagedDomainType<T> type, PersistentAttribute<T, ?> attribute) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
final AttributeContainer<T> container = (AttributeContainer<T>) type;
|
||||||
|
final AttributeContainer.InFlightAccess<T> inFlightAccess = container.getInFlightAccess();
|
||||||
final boolean virtual = attribute.getPersistentAttributeType() == Attribute.PersistentAttributeType.EMBEDDED
|
final boolean virtual = attribute.getPersistentAttributeType() == Attribute.PersistentAttributeType.EMBEDDED
|
||||||
&& attribute.getAttributeJavaType() instanceof EntityJavaType<?>;
|
&& attribute.getAttributeJavaType() instanceof EntityJavaType<?>;
|
||||||
if ( virtual ) {
|
if ( virtual ) {
|
||||||
final EmbeddableDomainType<?> embeddableDomainType = (EmbeddableDomainType<?>) attribute.getValueGraphType();
|
@SuppressWarnings("unchecked")
|
||||||
|
final EmbeddableDomainType<T> embeddableDomainType =
|
||||||
|
(EmbeddableDomainType<T>) attribute.getValueGraphType();
|
||||||
final Component component = componentByEmbeddable.get( embeddableDomainType );
|
final Component component = componentByEmbeddable.get( embeddableDomainType );
|
||||||
for ( Property property : component.getProperties() ) {
|
for ( Property property : component.getProperties() ) {
|
||||||
//noinspection unchecked
|
final PersistentAttribute<T, ?> subAttribute =
|
||||||
ManagedDomainType<Object> managedDomainType = (ManagedDomainType<Object>) embeddableDomainType;
|
attributeFactory.buildAttribute( embeddableDomainType, property );
|
||||||
final PersistentAttribute<Object, ?> subAttribute =
|
|
||||||
attributeFactory.buildAttribute( managedDomainType, property );
|
|
||||||
if ( subAttribute != null ) {
|
if ( subAttribute != null ) {
|
||||||
inFlightAccess.addAttribute( subAttribute );
|
inFlightAccess.addAttribute( subAttribute );
|
||||||
}
|
}
|
||||||
|
@ -473,43 +467,41 @@ public class MetadataContext {
|
||||||
// 2) register the part (mapping role)
|
// 2) register the part (mapping role)
|
||||||
// 3) somehow get the mapping role "into" the part (setter, ?)
|
// 3) somehow get the mapping role "into" the part (setter, ?)
|
||||||
|
|
||||||
private void applyIdMetadata(PersistentClass persistentClass, IdentifiableDomainType<?> identifiableType) {
|
private <T> void applyIdMetadata(PersistentClass persistentClass, IdentifiableDomainType<T> identifiableType) {
|
||||||
if ( persistentClass.hasIdentifierProperty() ) {
|
if ( persistentClass.hasIdentifierProperty() ) {
|
||||||
final Property declaredIdentifierProperty = persistentClass.getDeclaredIdentifierProperty();
|
final Property declaredIdentifierProperty = persistentClass.getDeclaredIdentifierProperty();
|
||||||
//noinspection rawtypes
|
@SuppressWarnings("unchecked")
|
||||||
final AttributeContainer attributeContainer = (AttributeContainer) identifiableType;
|
final AttributeContainer<T> attributeContainer = (AttributeContainer<T>) identifiableType;
|
||||||
if ( declaredIdentifierProperty != null ) {
|
if ( declaredIdentifierProperty != null ) {
|
||||||
//noinspection unchecked
|
final SingularPersistentAttribute<T, ?> idAttribute =
|
||||||
final SingularPersistentAttribute<?, Object> idAttribute = (SingularPersistentAttribute<?, Object>) buildAttribute(
|
(SingularPersistentAttribute<T, ?>)
|
||||||
|
buildAttribute(
|
||||||
declaredIdentifierProperty,
|
declaredIdentifierProperty,
|
||||||
identifiableType,
|
identifiableType,
|
||||||
attributeFactory::buildIdAttribute
|
attributeFactory::buildIdAttribute
|
||||||
);
|
);
|
||||||
//noinspection unchecked
|
|
||||||
attributeContainer.getInFlightAccess().applyIdAttribute( idAttribute );
|
attributeContainer.getInFlightAccess().applyIdAttribute( idAttribute );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
final Property superclassIdentifier = getMappedSuperclassIdentifier( persistentClass );
|
final Property superclassIdentifier = getMappedSuperclassIdentifier( persistentClass );
|
||||||
if ( superclassIdentifier != null && superclassIdentifier.isGeneric() ) {
|
if ( superclassIdentifier != null && superclassIdentifier.isGeneric() ) {
|
||||||
// If the superclass identifier is generic we have to build the attribute to register the concrete type
|
// If the superclass identifier is generic we have to build the attribute to register the concrete type
|
||||||
final SingularPersistentAttribute<?, Object> concreteIdentifier = attributeFactory.buildIdAttribute(
|
final SingularPersistentAttribute<T, ?> concreteIdentifier =
|
||||||
|
attributeFactory.buildIdAttribute(
|
||||||
identifiableType,
|
identifiableType,
|
||||||
persistentClass.getIdentifierProperty()
|
persistentClass.getIdentifierProperty()
|
||||||
);
|
);
|
||||||
//noinspection unchecked
|
|
||||||
attributeContainer.getInFlightAccess().addConcreteGenericAttribute( concreteIdentifier );
|
attributeContainer.getInFlightAccess().addConcreteGenericAttribute( concreteIdentifier );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// we have a non-aggregated composite-id
|
// we have a non-aggregated composite-id
|
||||||
|
if ( !( persistentClass.getIdentifier() instanceof Component compositeId ) ) {
|
||||||
if ( !(persistentClass.getIdentifier() instanceof Component) ) {
|
|
||||||
throw new MappingException( "Expecting Component for id mapping with no id-attribute" );
|
throw new MappingException( "Expecting Component for id mapping with no id-attribute" );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle the actual id-attributes
|
// Handle the actual id-attributes
|
||||||
final Component cidValue = (Component) persistentClass.getIdentifier();
|
|
||||||
final List<Property> cidProperties;
|
final List<Property> cidProperties;
|
||||||
final int propertySpan;
|
final int propertySpan;
|
||||||
final EmbeddableTypeImpl<?> idClassType;
|
final EmbeddableTypeImpl<?> idClassType;
|
||||||
|
@ -520,33 +512,39 @@ public class MetadataContext {
|
||||||
idClassType = applyIdClassMetadata( (Component) persistentClass.getIdentifier() );
|
idClassType = applyIdClassMetadata( (Component) persistentClass.getIdentifier() );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cidProperties = cidValue.getProperties();
|
cidProperties = compositeId.getProperties();
|
||||||
propertySpan = cidValue.getPropertySpan();
|
propertySpan = compositeId.getPropertySpan();
|
||||||
idClassType = null;
|
idClassType = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert cidValue.isEmbedded();
|
assert compositeId.isEmbedded();
|
||||||
|
|
||||||
AbstractIdentifiableType<?> idType = (AbstractIdentifiableType<?>)
|
final IdentifiableDomainType<?> idDomainType =
|
||||||
identifiableTypesByName.get( cidValue.getOwner().getEntityName() );
|
identifiableTypesByName.get( compositeId.getOwner().getEntityName() );
|
||||||
//noinspection rawtypes
|
@SuppressWarnings("unchecked")
|
||||||
Set idAttributes = idType.getIdClassAttributesSafely();
|
final AbstractIdentifiableType<T> idType = (AbstractIdentifiableType<T>) idDomainType;
|
||||||
|
applyIdAttributes( identifiableType, idType, propertySpan, cidProperties, idClassType );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> void applyIdAttributes(
|
||||||
|
IdentifiableDomainType<T> identifiableType,
|
||||||
|
AbstractIdentifiableType<T> idType,
|
||||||
|
int propertySpan,
|
||||||
|
List<Property> cidProperties,
|
||||||
|
EmbeddableTypeImpl<?> idClassType) {
|
||||||
|
Set<SingularPersistentAttribute<? super T, ?>> idAttributes = idType.getIdClassAttributesSafely();
|
||||||
if ( idAttributes == null ) {
|
if ( idAttributes == null ) {
|
||||||
idAttributes = new HashSet<>( propertySpan );
|
idAttributes = new HashSet<>( propertySpan );
|
||||||
for ( Property cidSubproperty : cidProperties ) {
|
for ( Property cidSubproperty : cidProperties ) {
|
||||||
final SingularPersistentAttribute<?, Object> cidSubAttr =
|
idAttributes.add( attributeFactory.buildIdAttribute( idType, cidSubproperty ) );
|
||||||
attributeFactory.buildIdAttribute( idType, cidSubproperty );
|
|
||||||
//noinspection unchecked
|
|
||||||
idAttributes.add( cidSubAttr );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
AttributeContainer<?> container = (AttributeContainer<?>) identifiableType;
|
final AttributeContainer<T> container = (AttributeContainer<T>) identifiableType;
|
||||||
//noinspection unchecked
|
|
||||||
container.getInFlightAccess().applyNonAggregatedIdAttributes( idAttributes, idClassType);
|
container.getInFlightAccess().applyNonAggregatedIdAttributes( idAttributes, idClassType);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private Property getMappedSuperclassIdentifier(PersistentClass persistentClass) {
|
private Property getMappedSuperclassIdentifier(PersistentClass persistentClass) {
|
||||||
MappedSuperclass mappedSuperclass = getMappedSuperclass( persistentClass );
|
MappedSuperclass mappedSuperclass = getMappedSuperclass( persistentClass );
|
||||||
|
@ -561,52 +559,48 @@ public class MetadataContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
private EmbeddableTypeImpl<?> applyIdClassMetadata(Component idClassComponent) {
|
private EmbeddableTypeImpl<?> applyIdClassMetadata(Component idClassComponent) {
|
||||||
final JavaTypeRegistry registry = getTypeConfiguration()
|
final JavaType<?> javaType =
|
||||||
.getJavaTypeRegistry();
|
getTypeConfiguration().getJavaTypeRegistry()
|
||||||
final Class<?> componentClass = idClassComponent.getComponentClass();
|
.resolveManagedTypeDescriptor( idClassComponent.getComponentClass() );
|
||||||
final JavaType<?> javaType = registry.resolveManagedTypeDescriptor( componentClass );
|
final EmbeddableTypeImpl<?> embeddableType =
|
||||||
|
new EmbeddableTypeImpl<>( javaType, null, null, false, getJpaMetamodel() );
|
||||||
final EmbeddableTypeImpl<?> embeddableType = new EmbeddableTypeImpl<>(
|
|
||||||
javaType,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
false,
|
|
||||||
getJpaMetamodel()
|
|
||||||
);
|
|
||||||
registerEmbeddableType( embeddableType, idClassComponent );
|
registerEmbeddableType( embeddableType, idClassComponent );
|
||||||
return embeddableType;
|
return embeddableType;
|
||||||
}
|
}
|
||||||
|
|
||||||
private <X> void applyIdMetadata(MappedSuperclass mappingType, MappedSuperclassDomainType<X> jpaMappingType) {
|
private <X> void applyIdMetadata(MappedSuperclass mappingType, MappedSuperclassDomainType<X> jpaMappingType) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
final AttributeContainer<X> attributeContainer = (AttributeContainer<X>) jpaMappingType;
|
||||||
if ( mappingType.hasIdentifierProperty() ) {
|
if ( mappingType.hasIdentifierProperty() ) {
|
||||||
final Property declaredIdentifierProperty = mappingType.getDeclaredIdentifierProperty();
|
final Property declaredIdentifierProperty = mappingType.getDeclaredIdentifierProperty();
|
||||||
if ( declaredIdentifierProperty != null ) {
|
if ( declaredIdentifierProperty != null ) {
|
||||||
//noinspection unchecked
|
final SingularPersistentAttribute<X, ?> attribute =
|
||||||
final SingularPersistentAttribute<X, Object> attribute = (SingularPersistentAttribute<X, Object>) buildAttribute(
|
(SingularPersistentAttribute<X, ?>)
|
||||||
|
buildAttribute(
|
||||||
declaredIdentifierProperty,
|
declaredIdentifierProperty,
|
||||||
jpaMappingType,
|
jpaMappingType,
|
||||||
attributeFactory::buildIdAttribute
|
attributeFactory::buildIdAttribute
|
||||||
);
|
);
|
||||||
//noinspection unchecked
|
attributeContainer.getInFlightAccess().applyIdAttribute( attribute );
|
||||||
( (AttributeContainer<X>) jpaMappingType ).getInFlightAccess().applyIdAttribute( attribute );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//a MappedSuperclass can have no identifier if the id is set below in the hierarchy
|
//a MappedSuperclass can have no identifier if the id is set below in the hierarchy
|
||||||
else if ( mappingType.getIdentifierMapper() != null ) {
|
else if ( mappingType.getIdentifierMapper() != null ) {
|
||||||
Set<SingularPersistentAttribute<? super X, ?>> attributes = buildIdClassAttributes(
|
final Set<SingularPersistentAttribute<? super X, ?>> attributes =
|
||||||
|
buildIdClassAttributes(
|
||||||
jpaMappingType,
|
jpaMappingType,
|
||||||
mappingType.getIdentifierMapper().getProperties()
|
mappingType.getIdentifierMapper().getProperties()
|
||||||
);
|
);
|
||||||
//noinspection unchecked
|
attributeContainer.getInFlightAccess().applyIdClassAttributes( attributes );
|
||||||
( ( AttributeContainer<X>) jpaMappingType ).getInFlightAccess().applyIdClassAttributes( attributes );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private <X> void applyVersionAttribute(PersistentClass persistentClass, EntityDomainType<X> jpaEntityType) {
|
private <X> void applyVersionAttribute(PersistentClass persistentClass, EntityDomainType<X> jpaEntityType) {
|
||||||
final Property declaredVersion = persistentClass.getDeclaredVersion();
|
final Property declaredVersion = persistentClass.getDeclaredVersion();
|
||||||
if ( declaredVersion != null ) {
|
if ( declaredVersion != null ) {
|
||||||
//noinspection unchecked
|
@SuppressWarnings("unchecked")
|
||||||
( ( AttributeContainer<X>) jpaEntityType ).getInFlightAccess().applyVersionAttribute(
|
final AttributeContainer<X> attributeContainer = (AttributeContainer<X>) jpaEntityType;
|
||||||
|
attributeContainer.getInFlightAccess().applyVersionAttribute(
|
||||||
attributeFactory.buildVersionAttribute( jpaEntityType, declaredVersion )
|
attributeFactory.buildVersionAttribute( jpaEntityType, declaredVersion )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -615,8 +609,9 @@ public class MetadataContext {
|
||||||
private <X> void applyVersionAttribute(MappedSuperclass mappingType, MappedSuperclassDomainType<X> jpaMappingType) {
|
private <X> void applyVersionAttribute(MappedSuperclass mappingType, MappedSuperclassDomainType<X> jpaMappingType) {
|
||||||
final Property declaredVersion = mappingType.getDeclaredVersion();
|
final Property declaredVersion = mappingType.getDeclaredVersion();
|
||||||
if ( declaredVersion != null ) {
|
if ( declaredVersion != null ) {
|
||||||
//noinspection unchecked
|
@SuppressWarnings("unchecked")
|
||||||
( ( AttributeContainer<X>) jpaMappingType ).getInFlightAccess().applyVersionAttribute(
|
final AttributeContainer<X> xAttributeContainer = (AttributeContainer<X>) jpaMappingType;
|
||||||
|
xAttributeContainer.getInFlightAccess().applyVersionAttribute(
|
||||||
attributeFactory.buildVersionAttribute( jpaMappingType, declaredVersion )
|
attributeFactory.buildVersionAttribute( jpaMappingType, declaredVersion )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -629,8 +624,9 @@ public class MetadataContext {
|
||||||
if ( superclassProperty.isGeneric() ) {
|
if ( superclassProperty.isGeneric() ) {
|
||||||
final Property property = persistentClass.getProperty( superclassProperty.getName() );
|
final Property property = persistentClass.getProperty( superclassProperty.getName() );
|
||||||
final PersistentAttribute<X, ?> attribute = attributeFactory.buildAttribute( entityType, property );
|
final PersistentAttribute<X, ?> attribute = attributeFactory.buildAttribute( entityType, property );
|
||||||
//noinspection unchecked
|
@SuppressWarnings("unchecked")
|
||||||
( (AttributeContainer<X>) entityType ).getInFlightAccess().addConcreteGenericAttribute( attribute );
|
final AttributeContainer<X> attributeContainer = (AttributeContainer<X>) entityType;
|
||||||
|
attributeContainer.getInFlightAccess().addConcreteGenericAttribute( attribute );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mappedSuperclass = getMappedSuperclass( mappedSuperclass );
|
mappedSuperclass = getMappedSuperclass( mappedSuperclass );
|
||||||
|
@ -695,13 +691,9 @@ public class MetadataContext {
|
||||||
|
|
||||||
private <X> void populateStaticMetamodel(ManagedDomainType<X> managedType, Set<String> processedMetamodelClassName) {
|
private <X> void populateStaticMetamodel(ManagedDomainType<X> managedType, Set<String> processedMetamodelClassName) {
|
||||||
final Class<X> managedTypeClass = managedType.getJavaType();
|
final Class<X> managedTypeClass = managedType.getJavaType();
|
||||||
if ( managedTypeClass == null ) {
|
if ( managedTypeClass != null // can be null for MAP entity mode, so skip...
|
||||||
// should indicate MAP entity mode, skip...
|
&& processedMetamodelClassName.add( metamodelClassName( managedType ) ) ) {
|
||||||
return;
|
final Class<?> metamodelClass = metamodelClass( managedType );
|
||||||
}
|
|
||||||
final String metamodelClassName = managedTypeClass.getName() + '_';
|
|
||||||
if ( processedMetamodelClassName.add( metamodelClassName ) ) {
|
|
||||||
final Class<?> metamodelClass = metamodelClass( metamodelClassName );
|
|
||||||
if ( metamodelClass != null ) {
|
if ( metamodelClass != null ) {
|
||||||
populateMetamodelClass( managedType, metamodelClass );
|
populateMetamodelClass( managedType, metamodelClass );
|
||||||
}
|
}
|
||||||
|
@ -718,13 +710,6 @@ public class MetadataContext {
|
||||||
private <X> void populateMetamodelClass(ManagedDomainType<X> managedType, Class<?> metamodelClass) {
|
private <X> void populateMetamodelClass(ManagedDomainType<X> managedType, Class<?> metamodelClass) {
|
||||||
registerAttributes( metamodelClass, managedType );
|
registerAttributes( metamodelClass, managedType );
|
||||||
injectManagedType( managedType, metamodelClass );
|
injectManagedType( managedType, metamodelClass );
|
||||||
runtimeModelCreationContext.getBootModel()
|
|
||||||
.visitNamedHqlQueryDefinitions( definition
|
|
||||||
-> injectTypedQueryReference( definition, metamodelClass) );
|
|
||||||
runtimeModelCreationContext.getBootModel()
|
|
||||||
.visitNamedNativeQueryDefinitions( definition
|
|
||||||
-> injectTypedQueryReference( definition, metamodelClass) );
|
|
||||||
//TODO: named entity graphs
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <X> void injectManagedType(ManagedDomainType<X> managedType, Class<?> metamodelClass) {
|
private static <X> void injectManagedType(ManagedDomainType<X> managedType, Class<?> metamodelClass) {
|
||||||
|
@ -736,7 +721,16 @@ public class MetadataContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Class<?> metamodelClass(String metamodelClassName) {
|
private static String metamodelClassName(ManagedDomainType<?> managedTypeClass) {
|
||||||
|
return managedTypeClass.getJavaType().getName() + '_';
|
||||||
|
}
|
||||||
|
|
||||||
|
public Class<?> metamodelClass(ManagedDomainType<?> managedDomainType) {
|
||||||
|
if ( managedDomainType == null ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
final String metamodelClassName = metamodelClassName( managedDomainType );
|
||||||
try {
|
try {
|
||||||
return classLoaderService.classForName( metamodelClassName );
|
return classLoaderService.classForName( metamodelClassName );
|
||||||
}
|
}
|
||||||
|
@ -744,35 +738,6 @@ public class MetadataContext {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void injectTypedQueryReference(NamedQueryDefinition<?> definition, Class<?> metamodelClass) {
|
|
||||||
try {
|
|
||||||
injectField(
|
|
||||||
metamodelClass,
|
|
||||||
'_' + javaIdentifier( definition.getRegistrationName() ) + '_',
|
|
||||||
definition,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
}
|
|
||||||
catch ( NoSuchFieldException e ) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String javaIdentifier(String name) {
|
|
||||||
final StringBuilder result = new StringBuilder();
|
|
||||||
int position = 0;
|
|
||||||
while ( position < name.length() ) {
|
|
||||||
final int codePoint = name.codePointAt( position );
|
|
||||||
if ( Character.isJavaIdentifierPart(codePoint) ) {
|
|
||||||
result.appendCodePoint( codePoint );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result.append('_');
|
|
||||||
}
|
|
||||||
position += charCount( codePoint );
|
|
||||||
}
|
|
||||||
return result.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private <X> void registerAttributes(Class<?> metamodelClass, ManagedDomainType<X> managedType) {
|
private <X> void registerAttributes(Class<?> metamodelClass, ManagedDomainType<X> managedType) {
|
||||||
|
@ -826,45 +791,6 @@ public class MetadataContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void injectField(
|
|
||||||
Class<?> metamodelClass, String name, Object model,
|
|
||||||
boolean allowNonDeclaredFieldReference)
|
|
||||||
throws NoSuchFieldException {
|
|
||||||
final Field field = allowNonDeclaredFieldReference
|
|
||||||
? metamodelClass.getField(name)
|
|
||||||
: metamodelClass.getDeclaredField(name);
|
|
||||||
try {
|
|
||||||
// should be public anyway, but to be sure...
|
|
||||||
ReflectHelper.ensureAccessibility( field );
|
|
||||||
field.set( null, model);
|
|
||||||
}
|
|
||||||
catch (IllegalAccessException e) {
|
|
||||||
// todo : exception type?
|
|
||||||
throw new AssertionFailure(
|
|
||||||
"Unable to inject static metamodel attribute : " + metamodelClass.getName() + '#' + name,
|
|
||||||
e
|
|
||||||
);
|
|
||||||
}
|
|
||||||
catch (IllegalArgumentException e) {
|
|
||||||
// most likely a mismatch in the type we are injecting and the defined field; this represents a
|
|
||||||
// mismatch in how the annotation processor interpreted the attribute and how our metamodel
|
|
||||||
// and/or annotation binder did.
|
|
||||||
|
|
||||||
// This is particularly the case as arrays are not handled properly by the StaticMetamodel generator
|
|
||||||
|
|
||||||
// throw new AssertionFailure(
|
|
||||||
// "Illegal argument on static metamodel field injection : " + metamodelClass.getName() + '#' + name
|
|
||||||
// + "; expected type : " + attribute.getClass().getName()
|
|
||||||
// + "; encountered type : " + field.getType().getName()
|
|
||||||
// );
|
|
||||||
log.illegalArgumentOnStaticMetamodelFieldInjection(
|
|
||||||
metamodelClass.getName(),
|
|
||||||
name,
|
|
||||||
model.getClass().getName(),
|
|
||||||
field.getType().getName()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public MappedSuperclassDomainType<?> locateMappedSuperclassType(MappedSuperclass mappedSuperclass) {
|
public MappedSuperclassDomainType<?> locateMappedSuperclassType(MappedSuperclass mappedSuperclass) {
|
||||||
return mappedSuperclassByMappedSuperclassMapping.get( mappedSuperclass );
|
return mappedSuperclassByMappedSuperclassMapping.get( mappedSuperclass );
|
||||||
|
@ -879,10 +805,8 @@ public class MetadataContext {
|
||||||
stackOfPersistentClassesBeingProcessed.size() - 1
|
stackOfPersistentClassesBeingProcessed.size() - 1
|
||||||
);
|
);
|
||||||
if ( stackTop != persistentClass ) {
|
if ( stackTop != persistentClass ) {
|
||||||
throw new AssertionFailure(
|
throw new AssertionFailure( "Inconsistent popping: "
|
||||||
"Inconsistent popping: "
|
+ persistentClass.getEntityName() + " instead of " + stackTop.getEntityName() );
|
||||||
+ persistentClass.getEntityName() + " instead of " + stackTop.getEntityName()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -903,20 +827,25 @@ public class MetadataContext {
|
||||||
private final Map<Class<?>,BasicDomainType<?>> basicDomainTypeMap = new HashMap<>();
|
private final Map<Class<?>,BasicDomainType<?>> basicDomainTypeMap = new HashMap<>();
|
||||||
|
|
||||||
public <J> BasicDomainType<J> resolveBasicType(Class<J> javaType) {
|
public <J> BasicDomainType<J> resolveBasicType(Class<J> javaType) {
|
||||||
//noinspection unchecked
|
@SuppressWarnings("unchecked")
|
||||||
return (BasicDomainType<J>) basicDomainTypeMap.computeIfAbsent(
|
final BasicDomainType<J> domainType = (BasicDomainType<J>) basicDomainTypeMap.get( javaType );
|
||||||
javaType,
|
if ( domainType == null ) {
|
||||||
jt -> {
|
|
||||||
// we cannot use getTypeConfiguration().standardBasicTypeForJavaType(javaType)
|
// we cannot use getTypeConfiguration().standardBasicTypeForJavaType(javaType)
|
||||||
// because that doesn't return the right thing for primitive types
|
// because that doesn't return the right thing for primitive types
|
||||||
final JavaTypeRegistry registry = getTypeConfiguration().getJavaTypeRegistry();
|
final JavaType<J> javaTypeDescriptor =
|
||||||
JavaType<J> javaTypeDescriptor = registry.resolveDescriptor( javaType );
|
getTypeConfiguration().getJavaTypeRegistry().resolveDescriptor( javaType );
|
||||||
JdbcType jdbcType = javaTypeDescriptor.getRecommendedJdbcType( typeConfiguration.getCurrentBaseSqlTypeIndicators() );
|
final JdbcType jdbcType =
|
||||||
return javaType.isPrimitive()
|
javaTypeDescriptor.getRecommendedJdbcType( typeConfiguration.getCurrentBaseSqlTypeIndicators() );
|
||||||
|
final BasicDomainType<J> type =
|
||||||
|
javaType.isPrimitive()
|
||||||
? new PrimitiveBasicTypeImpl<>( javaTypeDescriptor, jdbcType, javaType )
|
? new PrimitiveBasicTypeImpl<>( javaTypeDescriptor, jdbcType, javaType )
|
||||||
: new BasicTypeImpl<>( javaTypeDescriptor, jdbcType );
|
: new BasicTypeImpl<>( javaTypeDescriptor, jdbcType );
|
||||||
|
basicDomainTypeMap.put( javaType, type );
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return domainType;
|
||||||
}
|
}
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public <J> EmbeddableDomainType<J> locateEmbeddable(Class<J> embeddableClass, Component component) {
|
public <J> EmbeddableDomainType<J> locateEmbeddable(Class<J> embeddableClass, Component component) {
|
||||||
|
|
|
@ -21,6 +21,7 @@ import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import org.hibernate.boot.model.NamedEntityGraphDefinition;
|
import org.hibernate.boot.model.NamedEntityGraphDefinition;
|
||||||
|
import org.hibernate.boot.query.NamedQueryDefinition;
|
||||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||||
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
||||||
import org.hibernate.boot.spi.MetadataImplementor;
|
import org.hibernate.boot.spi.MetadataImplementor;
|
||||||
|
@ -32,7 +33,6 @@ import org.hibernate.graph.spi.RootGraphImplementor;
|
||||||
import org.hibernate.graph.spi.SubGraphImplementor;
|
import org.hibernate.graph.spi.SubGraphImplementor;
|
||||||
import org.hibernate.internal.CoreLogging;
|
import org.hibernate.internal.CoreLogging;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.internal.util.StringHelper;
|
|
||||||
import org.hibernate.jpa.spi.JpaCompliance;
|
import org.hibernate.jpa.spi.JpaCompliance;
|
||||||
import org.hibernate.mapping.MappedSuperclass;
|
import org.hibernate.mapping.MappedSuperclass;
|
||||||
import org.hibernate.mapping.PersistentClass;
|
import org.hibernate.mapping.PersistentClass;
|
||||||
|
@ -68,6 +68,9 @@ import jakarta.persistence.metamodel.ManagedType;
|
||||||
import jakarta.persistence.metamodel.Type;
|
import jakarta.persistence.metamodel.Type;
|
||||||
|
|
||||||
import static java.util.Collections.emptySet;
|
import static java.util.Collections.emptySet;
|
||||||
|
import static org.hibernate.internal.util.StringHelper.isNotEmpty;
|
||||||
|
import static org.hibernate.metamodel.internal.InjectionHelper.injectEntityGraph;
|
||||||
|
import static org.hibernate.metamodel.internal.InjectionHelper.injectTypedQueryReference;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -77,10 +80,10 @@ public class JpaMetamodelImpl implements JpaMetamodelImplementor, Serializable {
|
||||||
private static final CoreMessageLogger log = CoreLogging.messageLogger( JpaMetamodel.class );
|
private static final CoreMessageLogger log = CoreLogging.messageLogger( JpaMetamodel.class );
|
||||||
|
|
||||||
private static class ImportInfo<T> {
|
private static class ImportInfo<T> {
|
||||||
final String importedName;
|
private final String importedName;
|
||||||
Class<T> loadedClass; // could be null for boot metamodel import; not final to allow for populating later
|
private Class<T> loadedClass; // could be null for boot metamodel import; not final to allow for populating later
|
||||||
|
|
||||||
ImportInfo(String importedName, Class<T> loadedClass) {
|
private ImportInfo(String importedName, Class<T> loadedClass) {
|
||||||
this.importedName = importedName;
|
this.importedName = importedName;
|
||||||
this.loadedClass = loadedClass;
|
this.loadedClass = loadedClass;
|
||||||
}
|
}
|
||||||
|
@ -301,6 +304,7 @@ public class JpaMetamodelImpl implements JpaMetamodelImplementor, Serializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (NoSuchFieldException e) {
|
catch (NoSuchFieldException e) {
|
||||||
|
// ignore
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -429,7 +433,6 @@ public class JpaMetamodelImpl implements JpaMetamodelImplementor, Serializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private void applyNamedEntityGraphs(Collection<NamedEntityGraphDefinition> namedEntityGraphs) {
|
private void applyNamedEntityGraphs(Collection<NamedEntityGraphDefinition> namedEntityGraphs) {
|
||||||
for ( NamedEntityGraphDefinition definition : namedEntityGraphs ) {
|
for ( NamedEntityGraphDefinition definition : namedEntityGraphs ) {
|
||||||
log.debugf(
|
log.debugf(
|
||||||
|
@ -438,7 +441,7 @@ public class JpaMetamodelImpl implements JpaMetamodelImplementor, Serializable {
|
||||||
definition.getEntityName(),
|
definition.getEntityName(),
|
||||||
definition.getJpaEntityName()
|
definition.getJpaEntityName()
|
||||||
);
|
);
|
||||||
final EntityDomainType<Object> entityType = (EntityDomainType<Object>) entity( definition.getEntityName() );
|
final EntityDomainType<?> entityType = entity( definition.getEntityName() );
|
||||||
if ( entityType == null ) {
|
if ( entityType == null ) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Attempted to register named entity graph [" + definition.getRegisteredName()
|
"Attempted to register named entity graph [" + definition.getRegisteredName()
|
||||||
|
@ -446,47 +449,47 @@ public class JpaMetamodelImpl implements JpaMetamodelImplementor, Serializable {
|
||||||
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
final RootGraphImpl<Object> entityGraph = new RootGraphImpl<>( definition.getRegisteredName(), entityType );
|
|
||||||
|
|
||||||
final NamedEntityGraph namedEntityGraph = definition.getAnnotation();
|
final NamedEntityGraph namedEntityGraph = definition.getAnnotation();
|
||||||
|
final RootGraphImpl<?> entityGraph =
|
||||||
if ( namedEntityGraph.includeAllAttributes() ) {
|
createRootGraph( definition.getRegisteredName(), entityType,
|
||||||
for ( Attribute<? super Object, ?> attribute : entityType.getAttributes() ) {
|
namedEntityGraph.includeAllAttributes() );
|
||||||
entityGraph.addAttributeNodes( attribute );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( namedEntityGraph.attributeNodes() != null ) {
|
if ( namedEntityGraph.attributeNodes() != null ) {
|
||||||
applyNamedAttributeNodes( namedEntityGraph.attributeNodes(), namedEntityGraph, entityGraph );
|
applyNamedAttributeNodes( namedEntityGraph.attributeNodes(), namedEntityGraph, entityGraph );
|
||||||
}
|
}
|
||||||
|
|
||||||
entityGraphMap.put( definition.getRegisteredName(), entityGraph );
|
entityGraphMap.put( definition.getRegisteredName(), entityGraph );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static <T> RootGraphImpl<T> createRootGraph(
|
||||||
|
String name, EntityDomainType<T> entityType, boolean includeAllAttributes) {
|
||||||
|
final RootGraphImpl<T> entityGraph = new RootGraphImpl<>( name, entityType );
|
||||||
|
if ( includeAllAttributes ) {
|
||||||
|
for ( Attribute<? super T, ?> attribute : entityType.getAttributes() ) {
|
||||||
|
entityGraph.addAttributeNodes( attribute );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return entityGraph;
|
||||||
|
}
|
||||||
|
|
||||||
private void applyNamedAttributeNodes(
|
private void applyNamedAttributeNodes(
|
||||||
NamedAttributeNode[] namedAttributeNodes,
|
NamedAttributeNode[] namedAttributeNodes,
|
||||||
NamedEntityGraph namedEntityGraph,
|
NamedEntityGraph namedEntityGraph,
|
||||||
GraphImplementor<?> graphNode) {
|
GraphImplementor<?> graphNode) {
|
||||||
for ( NamedAttributeNode namedAttributeNode : namedAttributeNodes ) {
|
for ( NamedAttributeNode namedAttributeNode : namedAttributeNodes ) {
|
||||||
final String value = namedAttributeNode.value();
|
final AttributeNodeImplementor<?> attributeNode =
|
||||||
final AttributeNodeImplementor<?> attributeNode = graphNode.findOrCreateAttributeNode( value );
|
graphNode.findOrCreateAttributeNode( namedAttributeNode.value() );
|
||||||
if ( StringHelper.isNotEmpty( namedAttributeNode.subgraph() ) ) {
|
if ( isNotEmpty( namedAttributeNode.subgraph() ) ) {
|
||||||
final SubGraphImplementor<?> subgraph = attributeNode.makeSubGraph();
|
|
||||||
applyNamedSubgraphs(
|
applyNamedSubgraphs(
|
||||||
namedEntityGraph,
|
namedEntityGraph,
|
||||||
namedAttributeNode.subgraph(),
|
namedAttributeNode.subgraph(),
|
||||||
subgraph
|
attributeNode.makeSubGraph()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if ( StringHelper.isNotEmpty( namedAttributeNode.keySubgraph() ) ) {
|
if ( isNotEmpty( namedAttributeNode.keySubgraph() ) ) {
|
||||||
final SubGraphImplementor<?> subgraph = attributeNode.makeKeySubGraph();
|
|
||||||
|
|
||||||
applyNamedSubgraphs(
|
applyNamedSubgraphs(
|
||||||
namedEntityGraph,
|
namedEntityGraph,
|
||||||
namedAttributeNode.keySubgraph(),
|
namedAttributeNode.keySubgraph(),
|
||||||
subgraph
|
attributeNode.makeKeySubGraph()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -646,8 +649,7 @@ public class JpaMetamodelImpl implements JpaMetamodelImplementor, Serializable {
|
||||||
typeConfiguration.getJavaTypeRegistry().forEachDescriptor( descriptor -> {
|
typeConfiguration.getJavaTypeRegistry().forEachDescriptor( descriptor -> {
|
||||||
if ( descriptor instanceof EnumJavaType<? extends Enum<?>> enumJavaType ) {
|
if ( descriptor instanceof EnumJavaType<? extends Enum<?>> enumJavaType ) {
|
||||||
final Class<? extends Enum<?>> enumJavaClass = enumJavaType.getJavaTypeClass();
|
final Class<? extends Enum<?>> enumJavaClass = enumJavaType.getJavaTypeClass();
|
||||||
final Enum<?>[] enumConstants = enumJavaClass.getEnumConstants();
|
for ( Enum<?> enumConstant : enumJavaClass.getEnumConstants() ) {
|
||||||
for ( Enum<?> enumConstant : enumConstants ) {
|
|
||||||
addAllowedEnumLiteralsToEnumTypesMap(
|
addAllowedEnumLiteralsToEnumTypesMap(
|
||||||
allowedEnumLiteralsToEnumTypeNames,
|
allowedEnumLiteralsToEnumTypeNames,
|
||||||
enumConstant.name(),
|
enumConstant.name(),
|
||||||
|
@ -662,6 +664,26 @@ public class JpaMetamodelImpl implements JpaMetamodelImplementor, Serializable {
|
||||||
} );
|
} );
|
||||||
|
|
||||||
applyNamedEntityGraphs( namedEntityGraphDefinitions );
|
applyNamedEntityGraphs( namedEntityGraphDefinitions );
|
||||||
|
|
||||||
|
populateStaticMetamodel( bootMetamodel, context );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void populateStaticMetamodel(MetadataImplementor bootMetamodel, MetadataContext context) {
|
||||||
|
bootMetamodel.visitNamedHqlQueryDefinitions( definition
|
||||||
|
-> injectTypedQueryReference( definition, namedQueryMetamodelClass( definition, context ) ) );
|
||||||
|
bootMetamodel.visitNamedNativeQueryDefinitions( definition
|
||||||
|
-> injectTypedQueryReference( definition, namedQueryMetamodelClass( definition, context ) ) );
|
||||||
|
bootMetamodel.getNamedEntityGraphs().values().forEach(definition
|
||||||
|
-> injectEntityGraph( definition, graphMetamodelClass( definition, context ), this ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private Class<?> namedQueryMetamodelClass(NamedQueryDefinition<?> definition, MetadataContext context) {
|
||||||
|
final String location = definition.getLocation();
|
||||||
|
return location == null ? null : context.metamodelClass( managedTypeByName.get( location ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private Class<?> graphMetamodelClass(NamedEntityGraphDefinition definition, MetadataContext context) {
|
||||||
|
return context.metamodelClass( managedTypeByName.get( definition.getEntityName() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addAllowedEnumLiteralsToEnumTypesMap(
|
public static void addAllowedEnumLiteralsToEnumTypesMap(
|
||||||
|
|
|
@ -5,5 +5,6 @@
|
||||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
*/
|
*/
|
||||||
@NamedQuery(name = "allMouse",
|
@NamedQuery(name = "allMouse",
|
||||||
query = "select m from ApplicationServer m") package org.hibernate.orm.test.jpa.pack.defaultpar;
|
query = "select m from ApplicationServer m")
|
||||||
|
package org.hibernate.orm.test.jpa.pack.defaultpar;
|
||||||
import org.hibernate.annotations.NamedQuery;
|
import org.hibernate.annotations.NamedQuery;
|
||||||
|
|
Loading…
Reference in New Issue