JPA 3.2 support WIP

This commit is contained in:
Christian Beikov 2024-04-22 19:36:10 +02:00 committed by Steve Ebersole
parent 7490f4bede
commit 0b770f9b17
96 changed files with 3734 additions and 2989 deletions

View File

@ -17,6 +17,9 @@ public interface EntityManager extends AutoCloseable {
public interface EntityManagerFactory extends AutoCloseable { public interface EntityManagerFactory extends AutoCloseable {
public @Nullable Cache getCache(); public @Nullable Cache getCache();
} }
public interface EntityTransaction {
@Nullable Integer getTimeout();
}
public interface Parameter { public interface Parameter {
public @Nullable String getName(); public @Nullable String getName();
public @Nullable Integer getPosition(); public @Nullable Integer getPosition();

View File

@ -349,6 +349,31 @@ public final class Hibernate {
return true; return true;
} }
/**
* Initializes the property with the given name of the given entity instance.
* <p>
* This operation is equivalent to {@link jakarta.persistence.PersistenceUnitUtil#load(Object, String)}.
*
* @param proxy The entity instance or proxy
* @param attributeName the name of a persistent attribute of the object
*/
public static void initializeProperty(Object proxy, String attributeName) {
final Object entity;
final LazyInitializer lazyInitializer = extractLazyInitializer( proxy );
if ( lazyInitializer != null ) {
entity = lazyInitializer.getImplementation();
}
else {
entity = proxy;
}
if ( isPersistentAttributeInterceptable( entity ) ) {
PersistentAttributeInterceptor interceptor =
asPersistentAttributeInterceptable( entity ).$$_hibernate_getInterceptor();
interceptor.readObject( entity, attributeName, null );
}
}
/** /**
* If the given object is not a proxy, return it. But, if it is a proxy, ensure * If the given object is not a proxy, return it. But, if it is a proxy, ensure
* that the proxy is initialized, and return a direct reference to its proxied * that the proxy is initialized, and return a direct reference to its proxied

View File

@ -23,6 +23,7 @@ import jakarta.persistence.EntityManager;
import jakarta.persistence.FlushModeType; import jakarta.persistence.FlushModeType;
import jakarta.persistence.LockModeType; import jakarta.persistence.LockModeType;
import jakarta.persistence.PessimisticLockScope; import jakarta.persistence.PessimisticLockScope;
import jakarta.persistence.TypedQueryReference;
import jakarta.persistence.criteria.CriteriaDelete; import jakarta.persistence.criteria.CriteriaDelete;
import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.CriteriaUpdate; import jakarta.persistence.criteria.CriteriaUpdate;
@ -1574,6 +1575,9 @@ public interface Session extends SharedSessionContract, EntityManager {
@Override @Override
<R> Query<R> createQuery(String queryString, Class<R> resultClass); <R> Query<R> createQuery(String queryString, Class<R> resultClass);
@Override
<R> Query<R> createQuery(TypedQueryReference<R> typedQueryReference);
@Override @Deprecated @SuppressWarnings("rawtypes") @Override @Deprecated @SuppressWarnings("rawtypes")
Query createQuery(String queryString); Query createQuery(String queryString);

View File

@ -8,6 +8,7 @@ package org.hibernate;
import jakarta.persistence.EntityTransaction; import jakarta.persistence.EntityTransaction;
import jakarta.transaction.Synchronization; import jakarta.transaction.Synchronization;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.hibernate.resource.transaction.spi.TransactionStatus; import org.hibernate.resource.transaction.spi.TransactionStatus;
@ -66,7 +67,7 @@ public interface Transaction extends EntityTransaction {
* *
* @return The timeout, in seconds. * @return The timeout, in seconds.
*/ */
int getTimeout(); @Nullable Integer getTimeout();
/** /**
* Attempt to mark the underlying transaction for rollback only. * Attempt to mark the underlying transaction for rollback only.

View File

@ -12,6 +12,8 @@ import java.lang.annotation.Target;
import jakarta.persistence.CacheRetrieveMode; import jakarta.persistence.CacheRetrieveMode;
import jakarta.persistence.CacheStoreMode; import jakarta.persistence.CacheStoreMode;
import jakarta.persistence.EntityManager;
import org.hibernate.Remove; import org.hibernate.Remove;
import static java.lang.annotation.ElementType.PACKAGE; import static java.lang.annotation.ElementType.PACKAGE;
@ -47,6 +49,15 @@ public @interface NamedQuery {
*/ */
String query(); String query();
/**
* Optional query result class that is used by default when creating the query.
* May be overridden by explicitly passing a class object to
* {@link EntityManager#createNamedQuery(String, Class)}.
*
* @see jakarta.persistence.NamedQuery#resultClass()
*/
Class<?> resultClass() default void.class;
/** /**
* The flush mode for this query. * The flush mode for this query.
* *

View File

@ -115,24 +115,24 @@ public interface Metadata extends Mapping {
* *
* @return The named query metadata, or {@code null}. * @return The named query metadata, or {@code null}.
*/ */
NamedHqlQueryDefinition getNamedHqlQueryMapping(String name); NamedHqlQueryDefinition<?> getNamedHqlQueryMapping(String name);
/** /**
* Visit all named HQL query definitions * Visit all named HQL query definitions
*/ */
void visitNamedHqlQueryDefinitions(Consumer<NamedHqlQueryDefinition> definitionConsumer); void visitNamedHqlQueryDefinitions(Consumer<NamedHqlQueryDefinition<?>> definitionConsumer);
/** /**
* Retrieve named SQL query metadata. * Retrieve named SQL query metadata.
* *
* @return The named query metadata, or {@code null} * @return The named query metadata, or {@code null}
*/ */
NamedNativeQueryDefinition getNamedNativeQueryMapping(String name); NamedNativeQueryDefinition<?> getNamedNativeQueryMapping(String name);
/** /**
* Visit all named native query definitions * Visit all named native query definitions
*/ */
void visitNamedNativeQueryDefinitions(Consumer<NamedNativeQueryDefinition> definitionConsumer); void visitNamedNativeQueryDefinitions(Consumer<NamedNativeQueryDefinition<?>> definitionConsumer);
/** /**
* Retrieve named procedure metadata. * Retrieve named procedure metadata.

View File

@ -164,8 +164,8 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector,
private Database database; private Database database;
private final Map<String, NamedHqlQueryDefinition> namedQueryMap = new HashMap<>(); private final Map<String, NamedHqlQueryDefinition<?>> namedQueryMap = new HashMap<>();
private final Map<String, NamedNativeQueryDefinition> namedNativeQueryMap = new HashMap<>(); private final Map<String, NamedNativeQueryDefinition<?>> namedNativeQueryMap = new HashMap<>();
private final Map<String, NamedProcedureCallDefinition> namedProcedureCallMap = new HashMap<>(); private final Map<String, NamedProcedureCallDefinition> namedProcedureCallMap = new HashMap<>();
private final Map<String, NamedResultSetMappingDescriptor> sqlResultSetMappingMap = new HashMap<>(); private final Map<String, NamedResultSetMappingDescriptor> sqlResultSetMappingMap = new HashMap<>();
@ -763,7 +763,7 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector,
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Named query handling // Named query handling
public NamedHqlQueryDefinition getNamedHqlQueryMapping(String name) { public NamedHqlQueryDefinition<?> getNamedHqlQueryMapping(String name) {
if ( name == null ) { if ( name == null ) {
throw new IllegalArgumentException( "null is not a valid query name" ); throw new IllegalArgumentException( "null is not a valid query name" );
} }
@ -771,12 +771,12 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector,
} }
@Override @Override
public void visitNamedHqlQueryDefinitions(Consumer<NamedHqlQueryDefinition> definitionConsumer) { public void visitNamedHqlQueryDefinitions(Consumer<NamedHqlQueryDefinition<?>> definitionConsumer) {
namedQueryMap.values().forEach( definitionConsumer ); namedQueryMap.values().forEach( definitionConsumer );
} }
@Override @Override
public void addNamedQuery(NamedHqlQueryDefinition def) { public void addNamedQuery(NamedHqlQueryDefinition<?> def) {
if ( def == null ) { if ( def == null ) {
throw new IllegalArgumentException( "Named query definition is null" ); throw new IllegalArgumentException( "Named query definition is null" );
} }
@ -791,7 +791,7 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector,
applyNamedQuery( def.getRegistrationName(), def ); applyNamedQuery( def.getRegistrationName(), def );
} }
private void applyNamedQuery(String name, NamedHqlQueryDefinition query) { private void applyNamedQuery(String name, NamedHqlQueryDefinition<?> query) {
checkQueryName( name ); checkQueryName( name );
namedQueryMap.put( name.intern(), query ); namedQueryMap.put( name.intern(), query );
} }
@ -803,7 +803,7 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector,
} }
@Override @Override
public void addDefaultQuery(NamedHqlQueryDefinition queryDefinition) { public void addDefaultQuery(NamedHqlQueryDefinition<?> queryDefinition) {
applyNamedQuery( queryDefinition.getRegistrationName(), queryDefinition ); applyNamedQuery( queryDefinition.getRegistrationName(), queryDefinition );
defaultNamedQueryNames.add( queryDefinition.getRegistrationName() ); defaultNamedQueryNames.add( queryDefinition.getRegistrationName() );
} }
@ -812,17 +812,17 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector,
// Named native-query handling // Named native-query handling
@Override @Override
public NamedNativeQueryDefinition getNamedNativeQueryMapping(String name) { public NamedNativeQueryDefinition<?> getNamedNativeQueryMapping(String name) {
return namedNativeQueryMap.get( name ); return namedNativeQueryMap.get( name );
} }
@Override @Override
public void visitNamedNativeQueryDefinitions(Consumer<NamedNativeQueryDefinition> definitionConsumer) { public void visitNamedNativeQueryDefinitions(Consumer<NamedNativeQueryDefinition<?>> definitionConsumer) {
namedNativeQueryMap.values().forEach( definitionConsumer ); namedNativeQueryMap.values().forEach( definitionConsumer );
} }
@Override @Override
public void addNamedNativeQuery(NamedNativeQueryDefinition def) { public void addNamedNativeQuery(NamedNativeQueryDefinition<?> def) {
if ( def == null ) { if ( def == null ) {
throw new IllegalArgumentException( "Named native query definition object is null" ); throw new IllegalArgumentException( "Named native query definition object is null" );
} }
@ -837,13 +837,13 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector,
applyNamedNativeQuery( def.getRegistrationName(), def ); applyNamedNativeQuery( def.getRegistrationName(), def );
} }
private void applyNamedNativeQuery(String name, NamedNativeQueryDefinition query) { private void applyNamedNativeQuery(String name, NamedNativeQueryDefinition<?> query) {
checkQueryName( name ); checkQueryName( name );
namedNativeQueryMap.put( name.intern(), query ); namedNativeQueryMap.put( name.intern(), query );
} }
@Override @Override
public void addDefaultNamedNativeQuery(NamedNativeQueryDefinition query) { public void addDefaultNamedNativeQuery(NamedNativeQueryDefinition<?> query) {
applyNamedNativeQuery( query.getRegistrationName(), query ); applyNamedNativeQuery( query.getRegistrationName(), query );
defaultNamedNativeQueryNames.add( query.getRegistrationName() ); defaultNamedNativeQueryNames.add( query.getRegistrationName() );
} }

View File

@ -101,8 +101,8 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
private final Map<String, FetchProfile> fetchProfileMap; private final Map<String, FetchProfile> fetchProfileMap;
private final Map<String, String> imports; private final Map<String, String> imports;
private final Map<String, IdentifierGeneratorDefinition> idGeneratorDefinitionMap; private final Map<String, IdentifierGeneratorDefinition> idGeneratorDefinitionMap;
private final Map<String, NamedHqlQueryDefinition> namedQueryMap; private final Map<String, NamedHqlQueryDefinition<?>> namedQueryMap;
private final Map<String, NamedNativeQueryDefinition> namedNativeQueryMap; private final Map<String, NamedNativeQueryDefinition<?>> namedNativeQueryMap;
private final Map<String, NamedProcedureCallDefinition> namedProcedureCallMap; private final Map<String, NamedProcedureCallDefinition> namedProcedureCallMap;
private final Map<String, NamedResultSetMappingDescriptor> sqlResultSetMappingMap; private final Map<String, NamedResultSetMappingDescriptor> sqlResultSetMappingMap;
private final Map<String, NamedEntityGraphDefinition> namedEntityGraphMap; private final Map<String, NamedEntityGraphDefinition> namedEntityGraphMap;
@ -123,8 +123,8 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
Map<String, FetchProfile> fetchProfileMap, Map<String, FetchProfile> fetchProfileMap,
Map<String, String> imports, Map<String, String> imports,
Map<String, IdentifierGeneratorDefinition> idGeneratorDefinitionMap, Map<String, IdentifierGeneratorDefinition> idGeneratorDefinitionMap,
Map<String, NamedHqlQueryDefinition> namedQueryMap, Map<String, NamedHqlQueryDefinition<?>> namedQueryMap,
Map<String, NamedNativeQueryDefinition> namedNativeQueryMap, Map<String, NamedNativeQueryDefinition<?>> namedNativeQueryMap,
Map<String, NamedProcedureCallDefinition> namedProcedureCallMap, Map<String, NamedProcedureCallDefinition> namedProcedureCallMap,
Map<String, NamedResultSetMappingDescriptor> sqlResultSetMappingMap, Map<String, NamedResultSetMappingDescriptor> sqlResultSetMappingMap,
Map<String, NamedEntityGraphDefinition> namedEntityGraphMap, Map<String, NamedEntityGraphDefinition> namedEntityGraphMap,
@ -246,22 +246,22 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
} }
@Override @Override
public NamedHqlQueryDefinition getNamedHqlQueryMapping(String name) { public NamedHqlQueryDefinition<?> getNamedHqlQueryMapping(String name) {
return namedQueryMap.get( name ); return namedQueryMap.get( name );
} }
@Override @Override
public void visitNamedHqlQueryDefinitions(Consumer<NamedHqlQueryDefinition> definitionConsumer) { public void visitNamedHqlQueryDefinitions(Consumer<NamedHqlQueryDefinition<?>> definitionConsumer) {
namedQueryMap.values().forEach( definitionConsumer ); namedQueryMap.values().forEach( definitionConsumer );
} }
@Override @Override
public NamedNativeQueryDefinition getNamedNativeQueryMapping(String name) { public NamedNativeQueryDefinition<?> getNamedNativeQueryMapping(String name) {
return namedNativeQueryMap.get( name ); return namedNativeQueryMap.get( name );
} }
@Override @Override
public void visitNamedNativeQueryDefinitions(Consumer<NamedNativeQueryDefinition> definitionConsumer) { public void visitNamedNativeQueryDefinitions(Consumer<NamedNativeQueryDefinition<?>> definitionConsumer) {
namedNativeQueryMap.values().forEach( definitionConsumer ); namedNativeQueryMap.values().forEach( definitionConsumer );
} }
@ -370,16 +370,16 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
); );
} }
private Map<String, NamedSqmQueryMemento> buildNamedSqmMementos(SessionFactoryImplementor sessionFactory) { private Map<String, NamedSqmQueryMemento<?>> buildNamedSqmMementos(SessionFactoryImplementor sessionFactory) {
final HashMap<String, NamedSqmQueryMemento> map = new HashMap<>(); final HashMap<String, NamedSqmQueryMemento<?>> map = new HashMap<>();
if ( namedQueryMap != null ) { if ( namedQueryMap != null ) {
namedQueryMap.forEach( (key, value) -> map.put( key, value.resolve( sessionFactory ) ) ); namedQueryMap.forEach( (key, value) -> map.put( key, value.resolve( sessionFactory ) ) );
} }
return map; return map;
} }
private Map<String, NamedNativeQueryMemento> buildNamedNativeMementos(SessionFactoryImplementor sessionFactory) { private Map<String, NamedNativeQueryMemento<?>> buildNamedNativeMementos(SessionFactoryImplementor sessionFactory) {
final HashMap<String, NamedNativeQueryMemento> map = new HashMap<>(); final HashMap<String, NamedNativeQueryMemento<?>> map = new HashMap<>();
if ( namedNativeQueryMap != null ) { if ( namedNativeQueryMap != null ) {
namedNativeQueryMap.forEach( (key, value) -> map.put( key, value.resolve( sessionFactory ) ) ); namedNativeQueryMap.forEach( (key, value) -> map.put( key, value.resolve( sessionFactory ) ) );
} }
@ -652,11 +652,11 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
return bootstrapContext; return bootstrapContext;
} }
public Map<String, NamedHqlQueryDefinition> getNamedQueryMap() { public Map<String, NamedHqlQueryDefinition<?>> getNamedQueryMap() {
return namedQueryMap; return namedQueryMap;
} }
public Map<String, NamedNativeQueryDefinition> getNamedNativeQueryMap() { public Map<String, NamedNativeQueryDefinition<?>> getNamedNativeQueryMap() {
return namedNativeQueryMap; return namedNativeQueryMap;
} }

View File

@ -17,10 +17,12 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.query.hql.internal.NamedHqlQueryMementoImpl; import org.hibernate.query.hql.internal.NamedHqlQueryMementoImpl;
import org.hibernate.query.sqm.spi.NamedSqmQueryMemento; import org.hibernate.query.sqm.spi.NamedSqmQueryMemento;
import org.checkerframework.checker.nullness.qual.Nullable;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class NamedHqlQueryDefinitionImpl extends AbstractNamedQueryDefinition implements NamedHqlQueryDefinition { public class NamedHqlQueryDefinitionImpl<E> extends AbstractNamedQueryDefinition<E> implements NamedHqlQueryDefinition<E> {
private final String hqlString; private final String hqlString;
private final Integer firstResult; private final Integer firstResult;
private final Integer maxResults; private final Integer maxResults;
@ -28,6 +30,7 @@ public class NamedHqlQueryDefinitionImpl extends AbstractNamedQueryDefinition im
public NamedHqlQueryDefinitionImpl( public NamedHqlQueryDefinitionImpl(
String name, String name,
@Nullable Class<E> resultType,
String hqlString, String hqlString,
Integer firstResult, Integer firstResult,
Integer maxResults, Integer maxResults,
@ -44,6 +47,7 @@ public class NamedHqlQueryDefinitionImpl extends AbstractNamedQueryDefinition im
Map<String,Object> hints) { Map<String,Object> hints) {
super( super(
name, name,
resultType,
cacheable, cacheable,
cacheRegion, cacheRegion,
cacheMode, cacheMode,
@ -67,9 +71,10 @@ public class NamedHqlQueryDefinitionImpl extends AbstractNamedQueryDefinition im
} }
@Override @Override
public NamedSqmQueryMemento resolve(SessionFactoryImplementor factory) { public NamedSqmQueryMemento<E> resolve(SessionFactoryImplementor factory) {
return new NamedHqlQueryMementoImpl( return new NamedHqlQueryMementoImpl<>(
getRegistrationName(), getRegistrationName(),
getResultType(),
hqlString, hqlString,
firstResult, firstResult,
maxResults, maxResults,

View File

@ -18,24 +18,25 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.query.sql.internal.NamedNativeQueryMementoImpl; import org.hibernate.query.sql.internal.NamedNativeQueryMementoImpl;
import org.hibernate.query.sql.spi.NamedNativeQueryMemento; import org.hibernate.query.sql.spi.NamedNativeQueryMemento;
import org.checkerframework.checker.nullness.qual.Nullable;
import static org.hibernate.internal.util.StringHelper.isNotEmpty; import static org.hibernate.internal.util.StringHelper.isNotEmpty;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class NamedNativeQueryDefinitionImpl extends AbstractNamedQueryDefinition implements NamedNativeQueryDefinition { public class NamedNativeQueryDefinitionImpl<E> extends AbstractNamedQueryDefinition<E> implements NamedNativeQueryDefinition<E> {
private final String sqlString; private final String sqlString;
private final String resultSetMappingName; private final String resultSetMappingName;
private final String resultSetMappingClassName;
private final Set<String> querySpaces; private final Set<String> querySpaces;
private final Integer firstResult; private final Integer firstResult;
private final Integer maxResults; private final Integer maxResults;
public NamedNativeQueryDefinitionImpl( public NamedNativeQueryDefinitionImpl(
String name, String name,
@Nullable Class<E> resultType,
String sqlString, String sqlString,
String resultSetMappingName, String resultSetMappingName,
String resultSetMappingClassName,
Set<String> querySpaces, Set<String> querySpaces,
Boolean cacheable, Boolean cacheable,
String cacheRegion, String cacheRegion,
@ -50,6 +51,7 @@ public class NamedNativeQueryDefinitionImpl extends AbstractNamedQueryDefinition
Map<String,Object> hints) { Map<String,Object> hints) {
super( super(
name, name,
resultType,
cacheable, cacheable,
cacheRegion, cacheRegion,
cacheMode, cacheMode,
@ -63,7 +65,6 @@ public class NamedNativeQueryDefinitionImpl extends AbstractNamedQueryDefinition
); );
this.sqlString = sqlString; this.sqlString = sqlString;
this.resultSetMappingName = resultSetMappingName; this.resultSetMappingName = resultSetMappingName;
this.resultSetMappingClassName = resultSetMappingClassName;
this.querySpaces = querySpaces; this.querySpaces = querySpaces;
this.firstResult = firstResult; this.firstResult = firstResult;
this.maxResults = maxResults; this.maxResults = maxResults;
@ -80,21 +81,13 @@ public class NamedNativeQueryDefinitionImpl extends AbstractNamedQueryDefinition
} }
@Override @Override
public String getResultSetMappingClassName() { public NamedNativeQueryMemento<E> resolve(SessionFactoryImplementor factory) {
return resultSetMappingClassName; return new NamedNativeQueryMementoImpl<>(
}
@Override
public NamedNativeQueryMemento resolve(SessionFactoryImplementor factory) {
return new NamedNativeQueryMementoImpl(
getRegistrationName(), getRegistrationName(),
getResultType(),
sqlString, sqlString,
sqlString, sqlString,
resultSetMappingName, resultSetMappingName,
isNotEmpty( resultSetMappingClassName )
? factory.getServiceRegistry().requireService( ClassLoaderService.class )
.classForName( resultSetMappingClassName )
: null,
querySpaces, querySpaces,
getCacheable(), getCacheable(),
getCacheRegion(), getCacheRegion(),

View File

@ -2192,7 +2192,7 @@ public class HbmXmlTransformer {
version.setColumn( new JaxbColumnImpl() ); version.setColumn( new JaxbColumnImpl() );
version.getColumn().setName( hbmVersion.getColumnAttribute() ); version.getColumn().setName( hbmVersion.getColumnAttribute() );
} }
target.getAttributes().getVersion().add( version ); target.getAttributes().setVersion( version );
} }
} }
@ -2208,7 +2208,7 @@ public class HbmXmlTransformer {
} }
//noinspection deprecation //noinspection deprecation
version.setTemporal( TemporalType.TIMESTAMP ); version.setTemporal( TemporalType.TIMESTAMP );
target.getAttributes().getVersion().add( version ); target.getAttributes().setVersion( version );
} }
} }

View File

@ -11,90 +11,92 @@ import java.util.List;
import org.hibernate.annotations.PolymorphismType; import org.hibernate.annotations.PolymorphismType;
import org.hibernate.engine.OptimisticLockStyle; import org.hibernate.engine.OptimisticLockStyle;
import org.checkerframework.checker.nullness.qual.Nullable;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public interface JaxbEntity extends JaxbEntityOrMappedSuperclass { public interface JaxbEntity extends JaxbEntityOrMappedSuperclass {
String getName(); @Nullable String getName();
void setName(String name); void setName(@Nullable String name);
JaxbTableImpl getTable(); @Nullable JaxbTableImpl getTable();
void setTable(JaxbTableImpl value); void setTable(@Nullable JaxbTableImpl value);
String getTableExpression(); @Nullable String getTableExpression();
void setTableExpression(String value); void setTableExpression(@Nullable String value);
List<JaxbSecondaryTableImpl> getSecondaryTables(); List<JaxbSecondaryTableImpl> getSecondaryTables();
List<JaxbSynchronizedTableImpl> getSynchronizeTables(); List<JaxbSynchronizedTableImpl> getSynchronizeTables();
List<JaxbPrimaryKeyJoinColumnImpl> getPrimaryKeyJoinColumns(); List<JaxbPrimaryKeyJoinColumnImpl> getPrimaryKeyJoinColumns();
JaxbForeignKeyImpl getPrimaryKeyForeignKey(); @Nullable JaxbForeignKeyImpl getPrimaryKeyForeignKey();
void setPrimaryKeyForeignKey(JaxbForeignKeyImpl value); void setPrimaryKeyForeignKey(@Nullable JaxbForeignKeyImpl value);
String getRowid(); @Nullable String getRowid();
void setRowid(String value); void setRowid(@Nullable String value);
String getSqlRestriction(); @Nullable String getSqlRestriction();
void setSqlRestriction(String value); void setSqlRestriction(@Nullable String value);
JaxbSqlSelectImpl getSqlSelect(); @Nullable JaxbSqlSelectImpl getSqlSelect();
String getHqlSelect(); @Nullable String getHqlSelect();
JaxbCustomSqlImpl getSqlInsert(); @Nullable JaxbCustomSqlImpl getSqlInsert();
void setSqlInsert(JaxbCustomSqlImpl value); void setSqlInsert(JaxbCustomSqlImpl value);
JaxbCustomSqlImpl getSqlUpdate(); @Nullable JaxbCustomSqlImpl getSqlUpdate();
void setSqlUpdate(JaxbCustomSqlImpl value); void setSqlUpdate(@Nullable JaxbCustomSqlImpl value);
JaxbCustomSqlImpl getSqlDelete(); @Nullable JaxbCustomSqlImpl getSqlDelete();
void setSqlDelete(JaxbCustomSqlImpl value); void setSqlDelete(@Nullable JaxbCustomSqlImpl value);
Boolean isDynamicInsert(); @Nullable Boolean isDynamicInsert();
void setDynamicInsert(Boolean value); void setDynamicInsert(@Nullable Boolean value);
Boolean isDynamicUpdate(); @Nullable Boolean isDynamicUpdate();
void setDynamicUpdate(Boolean value); void setDynamicUpdate(@Nullable Boolean value);
Boolean isSelectBeforeUpdate(); @Nullable Boolean isSelectBeforeUpdate();
void setSelectBeforeUpdate(Boolean value); void setSelectBeforeUpdate(@Nullable Boolean value);
JaxbCachingImpl getCaching(); @Nullable JaxbCachingImpl getCaching();
void setCaching(JaxbCachingImpl value); void setCaching(@Nullable JaxbCachingImpl value);
Integer getBatchSize(); @Nullable Integer getBatchSize();
void setBatchSize(Integer value); void setBatchSize(@Nullable Integer value);
Boolean isLazy(); @Nullable Boolean isLazy();
void setLazy(Boolean value); void setLazy(@Nullable Boolean value);
Boolean isMutable(); @Nullable Boolean isMutable();
void setMutable(Boolean value); void setMutable(@Nullable Boolean value);
OptimisticLockStyle getOptimisticLocking(); @Nullable OptimisticLockStyle getOptimisticLocking();
void setOptimisticLocking(OptimisticLockStyle value); void setOptimisticLocking(@Nullable OptimisticLockStyle value);
JaxbInheritanceImpl getInheritance(); @Nullable JaxbInheritanceImpl getInheritance();
void setInheritance(JaxbInheritanceImpl value); void setInheritance(@Nullable JaxbInheritanceImpl value);
String getProxy(); @Nullable String getProxy();
void setProxy(String value); void setProxy(@Nullable String value);
PolymorphismType getPolymorphism(); @Nullable PolymorphismType getPolymorphism();
void setPolymorphism(PolymorphismType value); void setPolymorphism(@Nullable PolymorphismType value);
String getDiscriminatorValue(); @Nullable String getDiscriminatorValue();
void setDiscriminatorValue(String value); void setDiscriminatorValue(@Nullable String value);
JaxbDiscriminatorColumnImpl getDiscriminatorColumn(); @Nullable JaxbDiscriminatorColumnImpl getDiscriminatorColumn();
void setDiscriminatorColumn(JaxbDiscriminatorColumnImpl value); void setDiscriminatorColumn(@Nullable JaxbDiscriminatorColumnImpl value);
JaxbDiscriminatorFormulaImpl getDiscriminatorFormula(); @Nullable JaxbDiscriminatorFormulaImpl getDiscriminatorFormula();
void setDiscriminatorFormula(JaxbDiscriminatorFormulaImpl value); void setDiscriminatorFormula(@Nullable JaxbDiscriminatorFormulaImpl value);
JaxbSequenceGeneratorImpl getSequenceGenerators(); @Nullable JaxbSequenceGeneratorImpl getSequenceGenerators();
JaxbTableGeneratorImpl getTableGenerators(); @Nullable JaxbTableGeneratorImpl getTableGenerators();
List<JaxbGenericIdGeneratorImpl> getIdentifierGenerators(); List<JaxbGenericIdGeneratorImpl> getIdentifierGenerators();
@ -114,13 +116,13 @@ public interface JaxbEntity extends JaxbEntityOrMappedSuperclass {
List<JaxbFetchProfileImpl> getFetchProfiles(); List<JaxbFetchProfileImpl> getFetchProfiles();
JaxbTenantIdImpl getTenantId(); @Nullable JaxbTenantIdImpl getTenantId();
void setTenantId(JaxbTenantIdImpl value); void setTenantId(@Nullable JaxbTenantIdImpl value);
JaxbAttributesContainerImpl getAttributes(); @Nullable JaxbAttributesContainerImpl getAttributes();
void setAttributes(JaxbAttributesContainerImpl value); void setAttributes(@Nullable JaxbAttributesContainerImpl value);
Boolean isCacheable(); @Nullable Boolean isCacheable();
void setCacheable(Boolean value); void setCacheable(@Nullable Boolean value);
} }

View File

@ -6,25 +6,27 @@
*/ */
package org.hibernate.boot.jaxb.mapping.spi; package org.hibernate.boot.jaxb.mapping.spi;
import org.checkerframework.checker.nullness.qual.Nullable;
/** /**
* JAXB binding interface for commonality between entity and mapped-superclass mappings * JAXB binding interface for commonality between entity and mapped-superclass mappings
* *
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public interface JaxbEntityOrMappedSuperclass extends JaxbManagedType, JaxbLifecycleCallbackContainer { public interface JaxbEntityOrMappedSuperclass extends JaxbManagedType, JaxbLifecycleCallbackContainer {
JaxbIdClassImpl getIdClass(); @Nullable JaxbIdClassImpl getIdClass();
void setIdClass(JaxbIdClassImpl value); void setIdClass(@Nullable JaxbIdClassImpl value);
JaxbEmptyTypeImpl getExcludeDefaultListeners(); @Nullable JaxbEmptyTypeImpl getExcludeDefaultListeners();
void setExcludeDefaultListeners(JaxbEmptyTypeImpl value); void setExcludeDefaultListeners(@Nullable JaxbEmptyTypeImpl value);
JaxbEmptyTypeImpl getExcludeSuperclassListeners(); @Nullable JaxbEmptyTypeImpl getExcludeSuperclassListeners();
void setExcludeSuperclassListeners(JaxbEmptyTypeImpl value); void setExcludeSuperclassListeners(@Nullable JaxbEmptyTypeImpl value);
JaxbEntityListenerContainerImpl getEntityListenerContainer(); @Nullable JaxbEntityListenerContainerImpl getEntityListenerContainer();
void setEntityListenerContainer(JaxbEntityListenerContainerImpl value); void setEntityListenerContainer(@Nullable JaxbEntityListenerContainerImpl value);
} }

View File

@ -6,6 +6,8 @@
*/ */
package org.hibernate.boot.jaxb.mapping.spi; package org.hibernate.boot.jaxb.mapping.spi;
import org.checkerframework.checker.nullness.qual.Nullable;
/** /**
* JAXB binding interface for commonality between things which * JAXB binding interface for commonality between things which
* allow callback declarations. This includes <ul> * allow callback declarations. This includes <ul>
@ -20,24 +22,24 @@ package org.hibernate.boot.jaxb.mapping.spi;
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public interface JaxbLifecycleCallbackContainer { public interface JaxbLifecycleCallbackContainer {
JaxbPrePersistImpl getPrePersist(); @Nullable JaxbPrePersistImpl getPrePersist();
void setPrePersist(JaxbPrePersistImpl value); void setPrePersist(@Nullable JaxbPrePersistImpl value);
JaxbPostPersistImpl getPostPersist(); @Nullable JaxbPostPersistImpl getPostPersist();
void setPostPersist(JaxbPostPersistImpl value); void setPostPersist(@Nullable JaxbPostPersistImpl value);
JaxbPreRemoveImpl getPreRemove(); @Nullable JaxbPreRemoveImpl getPreRemove();
void setPreRemove(JaxbPreRemoveImpl value); void setPreRemove(@Nullable JaxbPreRemoveImpl value);
JaxbPostRemoveImpl getPostRemove(); @Nullable JaxbPostRemoveImpl getPostRemove();
void setPostRemove(JaxbPostRemoveImpl value); void setPostRemove(@Nullable JaxbPostRemoveImpl value);
JaxbPreUpdateImpl getPreUpdate(); @Nullable JaxbPreUpdateImpl getPreUpdate();
void setPreUpdate(JaxbPreUpdateImpl value); void setPreUpdate(@Nullable JaxbPreUpdateImpl value);
JaxbPostUpdateImpl getPostUpdate(); @Nullable JaxbPostUpdateImpl getPostUpdate();
void setPostUpdate(JaxbPostUpdateImpl value); void setPostUpdate(@Nullable JaxbPostUpdateImpl value);
JaxbPostLoadImpl getPostLoad(); @Nullable JaxbPostLoadImpl getPostLoad();
void setPostLoad(JaxbPostLoadImpl value); void setPostLoad(@Nullable JaxbPostLoadImpl value);
} }

View File

@ -7,6 +7,7 @@
package org.hibernate.boot.jaxb.mapping.spi; package org.hibernate.boot.jaxb.mapping.spi;
import jakarta.persistence.AccessType; import jakarta.persistence.AccessType;
import org.checkerframework.checker.nullness.qual.Nullable;
/** /**
* Common interface for JAXB bindings representing entities, mapped-superclasses and embeddables (JPA collective * Common interface for JAXB bindings representing entities, mapped-superclasses and embeddables (JPA collective
@ -17,21 +18,21 @@ import jakarta.persistence.AccessType;
*/ */
public interface JaxbManagedType { public interface JaxbManagedType {
String getDescription(); @Nullable String getDescription();
void setDescription(String value); void setDescription(@Nullable String value);
String getClazz(); @Nullable String getClazz();
void setClazz(String className); void setClazz(@Nullable String className);
Boolean isMetadataComplete(); @Nullable Boolean isMetadataComplete();
void setMetadataComplete(Boolean isMetadataComplete); void setMetadataComplete(@Nullable Boolean isMetadataComplete);
AccessType getAccess(); @Nullable AccessType getAccess();
void setAccess(AccessType value); void setAccess(@Nullable AccessType value);
JaxbAttributesContainer getAttributes(); @Nullable JaxbAttributesContainer getAttributes();
} }

View File

@ -19,4 +19,8 @@ public interface JaxbColumnSizable extends JaxbColumn {
default Integer getScale() { default Integer getScale() {
return null; return null;
} }
default Integer getSecondPrecision() {
return null;
}
} }

View File

@ -523,15 +523,18 @@ public abstract class AbstractPropertyHolder implements PropertyHolder {
String path, String path,
MetadataBuildingContext context) { MetadataBuildingContext context) {
int precision; int precision;
int secondPrecision;
final AnnotationUsage<Column> annotatedColumn = element.getAnnotationUsage( Column.class ); final AnnotationUsage<Column> annotatedColumn = element.getAnnotationUsage( Column.class );
if ( annotatedColumn != null ) { if ( annotatedColumn != null ) {
if ( StringHelper.isNotEmpty( annotatedColumn.getString( "name" ) ) ) { if ( StringHelper.isNotEmpty( annotatedColumn.getString( "name" ) ) ) {
return annotatedColumn; return annotatedColumn;
} }
precision = annotatedColumn.getInteger( "precision" ); precision = annotatedColumn.getInteger( "precision" );
secondPrecision = annotatedColumn.getInteger( "secondPrecision" );
} }
else { else {
precision = 0; precision = 0;
secondPrecision = -1;
} }
// Base the name of the synthetic dateTime field on the name of the original attribute // Base the name of the synthetic dateTime field on the name of the original attribute
@ -563,6 +566,7 @@ public abstract class AbstractPropertyHolder implements PropertyHolder {
(created) -> { (created) -> {
AnnotationUsageHelper.applyStringAttributeIfSpecified( "name", implicitName.getText(), created ); AnnotationUsageHelper.applyStringAttributeIfSpecified( "name", implicitName.getText(), created );
created.setAttributeValue( "precision", precision ); created.setAttributeValue( "precision", precision );
created.setAttributeValue( "secondPrecision", secondPrecision );
}, },
context.getMetadataCollector().getSourceModelBuildingContext() context.getMetadataCollector().getSourceModelBuildingContext()
); );
@ -644,6 +648,7 @@ public abstract class AbstractPropertyHolder implements PropertyHolder {
private final String columnDefinition; private final String columnDefinition;
private final String table; private final String table;
private final int precision; private final int precision;
private final int secondPrecision;
private ColumnImpl( private ColumnImpl(
String name, String name,
@ -653,7 +658,8 @@ public abstract class AbstractPropertyHolder implements PropertyHolder {
boolean updatable, boolean updatable,
String columnDefinition, String columnDefinition,
String table, String table,
int precision) { int precision,
int secondPrecision) {
this.name = name; this.name = name;
this.unique = unique; this.unique = unique;
this.nullable = nullable; this.nullable = nullable;
@ -662,6 +668,7 @@ public abstract class AbstractPropertyHolder implements PropertyHolder {
this.columnDefinition = columnDefinition; this.columnDefinition = columnDefinition;
this.table = table; this.table = table;
this.precision = precision; this.precision = precision;
this.secondPrecision = secondPrecision;
} }
@Override @Override
@ -719,6 +726,11 @@ public abstract class AbstractPropertyHolder implements PropertyHolder {
return 0; return 0;
} }
@Override
public int secondPrecision() {
return secondPrecision;
}
@Override @Override
public CheckConstraint[] check() { public CheckConstraint[] check() {
return new CheckConstraint[0]; return new CheckConstraint[0];

View File

@ -784,6 +784,11 @@ public class AnnotatedColumn {
} }
else { else {
annotatedColumn.setPrecision( column.getInteger( "precision" ) ); annotatedColumn.setPrecision( column.getInteger( "precision" ) );
// The passed annotation could also be a MapKeyColumn
Integer secondPrecision = column.getAnnotationType() == jakarta.persistence.Column.class
? column.getInteger( "secondPrecision" )
: null;
annotatedColumn.setTemporalPrecision( secondPrecision == null || secondPrecision == -1 ? null : secondPrecision );
} }
annotatedColumn.setScale( column.getInteger( "scale" ) ); annotatedColumn.setScale( column.getInteger( "scale" ) );
annotatedColumn.handleArrayLength( inferredData ); annotatedColumn.handleArrayLength( inferredData );

View File

@ -24,9 +24,9 @@ import org.hibernate.boot.internal.NamedProcedureCallDefinitionImpl;
import org.hibernate.boot.models.JpaAnnotations; import org.hibernate.boot.models.JpaAnnotations;
import org.hibernate.boot.query.NamedHqlQueryDefinition; import org.hibernate.boot.query.NamedHqlQueryDefinition;
import org.hibernate.boot.query.NamedNativeQueryDefinition; import org.hibernate.boot.query.NamedNativeQueryDefinition;
import org.hibernate.boot.query.NamedNativeQueryDefinitionBuilder;
import org.hibernate.boot.query.NamedProcedureCallDefinition; import org.hibernate.boot.query.NamedProcedureCallDefinition;
import org.hibernate.boot.query.SqlResultSetMappingDescriptor; import org.hibernate.boot.query.SqlResultSetMappingDescriptor;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.spi.MetadataBuildingContext; import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.log.DeprecationLogger; import org.hibernate.internal.log.DeprecationLogger;
@ -87,8 +87,9 @@ public abstract class QueryBinder {
final QueryHintDefinition hints = new QueryHintDefinition( queryName, namedQuery.getList( "hints" ) ); final QueryHintDefinition hints = new QueryHintDefinition( queryName, namedQuery.getList( "hints" ) );
final NamedHqlQueryDefinition queryMapping = new NamedHqlQueryDefinitionImpl.Builder( queryName ) final NamedHqlQueryDefinition<?> queryMapping = new NamedHqlQueryDefinitionImpl.Builder<>( queryName )
.setHqlString( queryString ) .setHqlString( queryString )
.setResultClass( loadClass( namedQuery.getClassDetails( "resultClass" ), context ) )
.setCacheable( hints.getCacheability() ) .setCacheable( hints.getCacheability() )
.setCacheMode( hints.getCacheMode() ) .setCacheMode( hints.getCacheMode() )
.setCacheRegion( hints.getString( HibernateHints.HINT_CACHE_REGION ) ) .setCacheRegion( hints.getString( HibernateHints.HINT_CACHE_REGION ) )
@ -108,6 +109,15 @@ public abstract class QueryBinder {
} }
} }
private static Class<Object> loadClass(ClassDetails classDetails, MetadataBuildingContext context) {
return ClassDetails.VOID_CLASS_DETAILS == classDetails
? null
: context.getBootstrapContext()
.getServiceRegistry()
.requireService( ClassLoaderService.class )
.classForName( classDetails.getName() );
}
public static void bindNativeQuery( public static void bindNativeQuery(
AnnotationUsage<NamedNativeQuery> namedNativeQuery, AnnotationUsage<NamedNativeQuery> namedNativeQuery,
MetadataBuildingContext context, MetadataBuildingContext context,
@ -127,14 +137,15 @@ public abstract class QueryBinder {
final String resultSetMappingName = namedNativeQuery.getString( "resultSetMapping" ); final String resultSetMappingName = namedNativeQuery.getString( "resultSetMapping" );
final ClassDetails resultClassDetails = namedNativeQuery.getClassDetails( "resultClass" ); final ClassDetails resultClassDetails = namedNativeQuery.getClassDetails( "resultClass" );
final String resultSetMappingClassName = ClassDetails.VOID_CLASS_DETAILS == resultClassDetails final Class<Object> resultClass = ClassDetails.VOID_CLASS_DETAILS == resultClassDetails
? null ? null
: resultClassDetails.getName(); : context.getBootstrapContext().getServiceRegistry().requireService( ClassLoaderService.class )
.classForName( resultClassDetails.getClassName() );
final NamedNativeQueryDefinitionBuilder builder = new NamedNativeQueryDefinitionBuilder( registrationName ) final NamedNativeQueryDefinition.Builder<?> builder = new NamedNativeQueryDefinition.Builder<>( registrationName )
.setSqlString( queryString ) .setSqlString( queryString )
.setResultClass( resultClass )
.setResultSetMappingName( resultSetMappingName ) .setResultSetMappingName( resultSetMappingName )
.setResultSetMappingClassName( resultSetMappingClassName )
.setQuerySpaces( null ) .setQuerySpaces( null )
.setCacheable( hints.getCacheability() ) .setCacheable( hints.getCacheability() )
.setCacheMode( hints.getCacheMode() ) .setCacheMode( hints.getCacheMode() )
@ -146,7 +157,7 @@ public abstract class QueryBinder {
.setComment( hints.getString( HibernateHints.HINT_COMMENT ) ) .setComment( hints.getString( HibernateHints.HINT_COMMENT ) )
.addHints( hints.getHintsMap() ); .addHints( hints.getHintsMap() );
final NamedNativeQueryDefinition queryDefinition = builder.build(); final NamedNativeQueryDefinition<?> queryDefinition = builder.build();
if ( LOG.isDebugEnabled() ) { if ( LOG.isDebugEnabled() ) {
LOG.debugf( "Binding named native query: %s => %s", queryDefinition.getRegistrationName(), queryDefinition.getSqlQueryString() ); LOG.debugf( "Binding named native query: %s => %s", queryDefinition.getRegistrationName(), queryDefinition.getSqlQueryString() );
@ -165,13 +176,16 @@ public abstract class QueryBinder {
AnnotationUsage<SQLSelect> sqlSelect, AnnotationUsage<SQLSelect> sqlSelect,
ClassDetails annotatedClass, ClassDetails annotatedClass,
MetadataBuildingContext context) { MetadataBuildingContext context) {
final NamedNativeQueryDefinitionBuilder builder = new NamedNativeQueryDefinitionBuilder( name ) final NamedNativeQueryDefinition.Builder<?> builder = new NamedNativeQueryDefinition.Builder<>( name )
.setFlushMode( FlushMode.MANUAL ) .setFlushMode( FlushMode.MANUAL )
.setSqlString( sqlSelect.getString( "sql" ) ) .setSqlString( sqlSelect.getString( "sql" ) )
.setQuerySpaces( setOf( sqlSelect.getList( "querySpaces" ) ) ); .setQuerySpaces( setOf( sqlSelect.getList( "querySpaces" ) ) );
if ( annotatedClass != null ) { if ( annotatedClass != null ) {
builder.setResultSetMappingClassName( annotatedClass.getName() ); builder.setResultClass(
context.getBootstrapContext().getServiceRegistry().requireService( ClassLoaderService.class )
.classForName( annotatedClass.getClassName() )
);
} }
final AnnotationUsage<SqlResultSetMapping> resultSetMapping = sqlSelect.getNestedUsage( "resultSetMapping" ); final AnnotationUsage<SqlResultSetMapping> resultSetMapping = sqlSelect.getNestedUsage( "resultSetMapping" );
@ -201,9 +215,10 @@ public abstract class QueryBinder {
final String resultSetMappingName = namedNativeQuery.getString( "resultSetMapping" ); final String resultSetMappingName = namedNativeQuery.getString( "resultSetMapping" );
final ClassDetails resultClassDetails = namedNativeQuery.getClassDetails( "resultClass" ); final ClassDetails resultClassDetails = namedNativeQuery.getClassDetails( "resultClass" );
final String resultSetMappingClassName = ClassDetails.VOID_CLASS_DETAILS == resultClassDetails final Class<Object> resultClass = ClassDetails.VOID_CLASS_DETAILS == resultClassDetails
? null ? null
: resultClassDetails.getName(); : context.getBootstrapContext().getServiceRegistry().requireService( ClassLoaderService.class )
.classForName( resultClassDetails.getClassName() );
final Integer timeout = namedNativeQuery.getInteger( "timeout" ); final Integer timeout = namedNativeQuery.getInteger( "timeout" );
final Integer fetchSize = namedNativeQuery.getInteger( "fetchSize" ); final Integer fetchSize = namedNativeQuery.getInteger( "fetchSize" );
@ -212,10 +227,10 @@ public abstract class QueryBinder {
final HashSet<String> querySpaces = new HashSet<>( determineProperSizing( querySpacesList.size() ) ); final HashSet<String> querySpaces = new HashSet<>( determineProperSizing( querySpacesList.size() ) );
querySpaces.addAll( querySpacesList ); querySpaces.addAll( querySpacesList );
final NamedNativeQueryDefinitionBuilder builder = new NamedNativeQueryDefinitionBuilder( registrationName ) final NamedNativeQueryDefinition.Builder<?> builder = new NamedNativeQueryDefinition.Builder<>( registrationName )
.setSqlString( namedNativeQuery.getString( "query" ) ) .setSqlString( namedNativeQuery.getString( "query" ) )
.setResultSetMappingName( resultSetMappingName ) .setResultSetMappingName( resultSetMappingName )
.setResultSetMappingClassName( resultSetMappingClassName ) .setResultClass( resultClass )
.setCacheable( namedNativeQuery.getBoolean( "cacheable" ) ) .setCacheable( namedNativeQuery.getBoolean( "cacheable" ) )
.setCacheRegion( nullIfEmpty( namedNativeQuery.getString( "cacheRegion" ) ) ) .setCacheRegion( nullIfEmpty( namedNativeQuery.getString( "cacheRegion" ) ) )
.setCacheMode( getCacheMode( namedNativeQuery ) ) .setCacheMode( getCacheMode( namedNativeQuery ) )
@ -235,7 +250,7 @@ public abstract class QueryBinder {
); );
} }
else { else {
final NamedNativeQueryDefinition queryDefinition = builder.build(); final NamedNativeQueryDefinition<?> queryDefinition = builder.build();
if ( LOG.isDebugEnabled() ) { if ( LOG.isDebugEnabled() ) {
LOG.debugf( LOG.debugf(
@ -250,7 +265,7 @@ public abstract class QueryBinder {
} }
public static NamedProcedureCallDefinition createStoredProcedure( public static NamedProcedureCallDefinition createStoredProcedure(
NamedNativeQueryDefinitionBuilder builder, NamedNativeQueryDefinition.Builder<?> builder,
MetadataBuildingContext context, MetadataBuildingContext context,
Supplier<RuntimeException> exceptionProducer) { Supplier<RuntimeException> exceptionProducer) {
final String sqlString = builder.getSqlString().trim(); final String sqlString = builder.getSqlString().trim();
@ -298,17 +313,10 @@ public abstract class QueryBinder {
nameStoredProcedureQueryAnn.setAttributeValue( "resultSetMappings", resultSetMappings ); nameStoredProcedureQueryAnn.setAttributeValue( "resultSetMappings", resultSetMappings );
} }
final String resultSetMappingClassName = builder.getResultSetMappingClassName(); final Class<?> resultClass = builder.getResultClass();
if ( resultSetMappingClassName != null ) { if ( resultClass != null ) {
final List<ClassDetails> resultClasses = new ArrayList<>( 1 ); final List<ClassDetails> resultClasses = new ArrayList<>( 1 );
final ClassDetails classDetails; final ClassDetails classDetails = nameStoredProcedureQueryAnn.getClassDetails( resultClass.getName() );
if ( StringHelper.isEmpty( resultSetMappingClassName ) ) {
classDetails = ClassDetails.VOID_CLASS_DETAILS;
}
else {
classDetails = nameStoredProcedureQueryAnn.getClassDetails( resultSetMappingClassName );
}
resultClasses.add( classDetails ); resultClasses.add( classDetails );
nameStoredProcedureQueryAnn.setAttributeValue( "resultClasses", resultClasses ); nameStoredProcedureQueryAnn.setAttributeValue( "resultClasses", resultClasses );
} }
@ -344,7 +352,7 @@ public abstract class QueryBinder {
String name, String name,
AnnotationUsage<HQLSelect> hqlSelect, AnnotationUsage<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.getString( "query" ) ) .setHqlString( hqlSelect.getString( "query" ) )
.build(); .build();
@ -369,8 +377,9 @@ public abstract class QueryBinder {
final Integer timeout = namedQuery.getInteger( "timeout" ); final Integer timeout = namedQuery.getInteger( "timeout" );
final Integer fetchSize = namedQuery.getInteger( "fetchSize" ); final Integer fetchSize = namedQuery.getInteger( "fetchSize" );
final NamedHqlQueryDefinition.Builder builder = new NamedHqlQueryDefinition.Builder( registrationName ) final NamedHqlQueryDefinition.Builder<?> builder = new NamedHqlQueryDefinition.Builder<>( registrationName )
.setHqlString( namedQuery.getString( "query" ) ) .setHqlString( namedQuery.getString( "query" ) )
.setResultClass( loadClass( namedQuery.getClassDetails( "resultClass" ), context ) )
.setCacheable( namedQuery.getBoolean( "cacheable" ) ) .setCacheable( namedQuery.getBoolean( "cacheable" ) )
.setCacheRegion( nullIfEmpty( namedQuery.getString( "cacheRegion" ) ) ) .setCacheRegion( nullIfEmpty( namedQuery.getString( "cacheRegion" ) ) )
.setCacheMode( getCacheMode( namedQuery ) ) .setCacheMode( getCacheMode( namedQuery ) )
@ -380,7 +389,7 @@ public abstract class QueryBinder {
.setReadOnly( namedQuery.getBoolean( "readOnly" ) ) .setReadOnly( namedQuery.getBoolean( "readOnly" ) )
.setComment( nullIfEmpty( namedQuery.getString( "comment" ) ) ); .setComment( nullIfEmpty( namedQuery.getString( "comment" ) ) );
final NamedHqlQueryDefinitionImpl hqlQueryDefinition = builder.build(); final NamedHqlQueryDefinitionImpl<?> hqlQueryDefinition = builder.build();
if ( LOG.isDebugEnabled() ) { if ( LOG.isDebugEnabled() ) {
LOG.debugf( "Binding named query: %s => %s", hqlQueryDefinition.getRegistrationName(), hqlQueryDefinition.getHqlString() ); LOG.debugf( "Binding named query: %s => %s", hqlQueryDefinition.getRegistrationName(), hqlQueryDefinition.getHqlString() );

View File

@ -20,7 +20,7 @@ import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmSynchronizeType;
import org.hibernate.boot.model.internal.QueryBinder; import org.hibernate.boot.model.internal.QueryBinder;
import org.hibernate.boot.query.ImplicitHbmResultSetMappingDescriptorBuilder; import org.hibernate.boot.query.ImplicitHbmResultSetMappingDescriptorBuilder;
import org.hibernate.boot.query.NamedHqlQueryDefinition; import org.hibernate.boot.query.NamedHqlQueryDefinition;
import org.hibernate.boot.query.NamedNativeQueryDefinitionBuilder; import org.hibernate.boot.query.NamedNativeQueryDefinition;
import org.hibernate.boot.query.NamedProcedureCallDefinition; import org.hibernate.boot.query.NamedProcedureCallDefinition;
import org.hibernate.internal.log.DeprecationLogger; import org.hibernate.internal.log.DeprecationLogger;
@ -49,7 +49,7 @@ 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() )
@ -111,7 +111,7 @@ public class NamedQueryBinder {
final String registrationName = prefix + namedQueryBinding.getName(); final String registrationName = prefix + namedQueryBinding.getName();
final NamedNativeQueryDefinitionBuilder builder = new NamedNativeQueryDefinitionBuilder( 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() )
@ -197,7 +197,7 @@ public class NamedQueryBinder {
private static boolean processNamedQueryContentItem( private static boolean processNamedQueryContentItem(
Object content, Object content,
NamedNativeQueryDefinitionBuilder queryBuilder, NamedNativeQueryDefinition.Builder<?> queryBuilder,
ImplicitHbmResultSetMappingDescriptorBuilder implicitResultSetMappingBuilder, ImplicitHbmResultSetMappingDescriptorBuilder implicitResultSetMappingBuilder,
JaxbHbmNamedNativeQueryType namedQueryBinding, JaxbHbmNamedNativeQueryType namedQueryBinding,
HbmLocalMetadataBuildingContext context) { HbmLocalMetadataBuildingContext context) {

View File

@ -9,16 +9,13 @@ package org.hibernate.boot.models.bind.internal;
import java.util.function.Supplier; import java.util.function.Supplier;
import org.hibernate.annotations.DiscriminatorFormula; import org.hibernate.annotations.DiscriminatorFormula;
import org.hibernate.boot.models.bind.internal.BindingHelper;
import org.hibernate.boot.models.bind.spi.BindingContext; import org.hibernate.boot.models.bind.spi.BindingContext;
import org.hibernate.boot.models.bind.spi.BindingOptions; import org.hibernate.boot.models.bind.spi.BindingOptions;
import org.hibernate.boot.models.bind.spi.BindingState; import org.hibernate.boot.models.bind.spi.BindingState;
import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.StringHelper;
import org.hibernate.mapping.BasicValue; import org.hibernate.mapping.BasicValue;
import org.hibernate.mapping.Column; import org.hibernate.mapping.Column;
import org.hibernate.mapping.DependantValue;
import org.hibernate.mapping.Formula; import org.hibernate.mapping.Formula;
import org.hibernate.mapping.Table;
import org.hibernate.models.spi.AnnotationDescriptor; import org.hibernate.models.spi.AnnotationDescriptor;
import org.hibernate.models.spi.AnnotationUsage; import org.hibernate.models.spi.AnnotationUsage;
@ -41,7 +38,8 @@ public class ColumnHelper {
true, true,
255, 255,
0, 0,
0 0,
-1
); );
} }
@ -57,7 +55,8 @@ public class ColumnHelper {
nullableByDefault, nullableByDefault,
255, 255,
0, 0,
0 0,
-1
); );
} }
@ -68,7 +67,8 @@ public class ColumnHelper {
boolean nullableByDefault, boolean nullableByDefault,
int lengthByDefault, int lengthByDefault,
int precisionByDefault, int precisionByDefault,
int scaleByDefault) { int scaleByDefault,
int secondPrecisionByDefault) {
final Column result = new Column(); final Column result = new Column();
result.setName( columnName( annotationUsage, defaultNameSupplier ) ); result.setName( columnName( annotationUsage, defaultNameSupplier ) );
@ -77,6 +77,7 @@ public class ColumnHelper {
result.setSqlType( BindingHelper.getValue( annotationUsage, "columnDefinition", (String) null ) ); result.setSqlType( BindingHelper.getValue( annotationUsage, "columnDefinition", (String) null ) );
result.setLength( BindingHelper.getValue( annotationUsage, "length", lengthByDefault ) ); result.setLength( BindingHelper.getValue( annotationUsage, "length", lengthByDefault ) );
result.setPrecision( BindingHelper.getValue( annotationUsage, "precision", precisionByDefault ) ); result.setPrecision( BindingHelper.getValue( annotationUsage, "precision", precisionByDefault ) );
result.setPrecision( BindingHelper.getValue( annotationUsage, "secondPrecision", secondPrecisionByDefault ) );
result.setScale( BindingHelper.getValue( annotationUsage, "scale", scaleByDefault ) ); result.setScale( BindingHelper.getValue( annotationUsage, "scale", scaleByDefault ) );
return result; return result;
} }

View File

@ -930,7 +930,7 @@ public class GlobalRegistrationsImpl implements GlobalRegistrations {
results.add( result ); results.add( result );
result.setAttributeValue( result.setAttributeValue(
"entityClass", "targetClass",
sourceModelContext.getClassDetailsRegistry().resolveClassDetails( jaxbConstructorResult.getTargetClass() ) sourceModelContext.getClassDetailsRegistry().resolveClassDetails( jaxbConstructorResult.getTargetClass() )
); );

View File

@ -6,12 +6,19 @@
*/ */
package org.hibernate.boot.models.xml.internal; package org.hibernate.boot.models.xml.internal;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.boot.jaxb.mapping.spi.JaxbAnyMappingImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbAnyMappingImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbAssociationOverrideImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbAttributeOverrideImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbAttributesContainer; import org.hibernate.boot.jaxb.mapping.spi.JaxbAttributesContainer;
import org.hibernate.boot.jaxb.mapping.spi.JaxbBaseAttributesContainer; import org.hibernate.boot.jaxb.mapping.spi.JaxbBaseAttributesContainer;
import org.hibernate.boot.jaxb.mapping.spi.JaxbBasicImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbBasicImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbElementCollectionImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbElementCollectionImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbEmbeddedImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbEmbeddedImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbForeignKeyImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbJoinTableImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbManyToManyImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbManyToManyImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbManyToOneImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbManyToOneImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbNaturalId; import org.hibernate.boot.jaxb.mapping.spi.JaxbNaturalId;
@ -19,8 +26,10 @@ import org.hibernate.boot.jaxb.mapping.spi.JaxbOneToManyImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbOneToOneImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbOneToOneImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbPersistentAttribute; import org.hibernate.boot.jaxb.mapping.spi.JaxbPersistentAttribute;
import org.hibernate.boot.jaxb.mapping.spi.JaxbPluralAnyMappingImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbPluralAnyMappingImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbTransientImpl;
import org.hibernate.boot.models.xml.internal.attr.AnyMappingAttributeProcessing; import org.hibernate.boot.models.xml.internal.attr.AnyMappingAttributeProcessing;
import org.hibernate.boot.models.xml.internal.attr.BasicAttributeProcessing; import org.hibernate.boot.models.xml.internal.attr.BasicAttributeProcessing;
import org.hibernate.boot.models.xml.internal.attr.CommonAttributeProcessing;
import org.hibernate.boot.models.xml.internal.attr.ElementCollectionAttributeProcessing; import org.hibernate.boot.models.xml.internal.attr.ElementCollectionAttributeProcessing;
import org.hibernate.boot.models.xml.internal.attr.EmbeddedAttributeProcessing; import org.hibernate.boot.models.xml.internal.attr.EmbeddedAttributeProcessing;
import org.hibernate.boot.models.xml.internal.attr.ManyToManyAttributeProcessing; import org.hibernate.boot.models.xml.internal.attr.ManyToManyAttributeProcessing;
@ -28,11 +37,21 @@ import org.hibernate.boot.models.xml.internal.attr.ManyToOneAttributeProcessing;
import org.hibernate.boot.models.xml.internal.attr.OneToManyAttributeProcessing; import org.hibernate.boot.models.xml.internal.attr.OneToManyAttributeProcessing;
import org.hibernate.boot.models.xml.internal.attr.OneToOneAttributeProcessing; import org.hibernate.boot.models.xml.internal.attr.OneToOneAttributeProcessing;
import org.hibernate.boot.models.xml.internal.attr.PluralAnyMappingAttributeProcessing; import org.hibernate.boot.models.xml.internal.attr.PluralAnyMappingAttributeProcessing;
import org.hibernate.boot.models.xml.internal.db.ColumnProcessing;
import org.hibernate.boot.models.xml.internal.db.ForeignKeyProcessing;
import org.hibernate.boot.models.xml.internal.db.JoinColumnProcessing;
import org.hibernate.boot.models.xml.internal.db.TableProcessing;
import org.hibernate.boot.models.xml.spi.XmlDocumentContext; import org.hibernate.boot.models.xml.spi.XmlDocumentContext;
import org.hibernate.models.spi.MutableAnnotationUsage;
import org.hibernate.models.spi.MutableClassDetails; import org.hibernate.models.spi.MutableClassDetails;
import org.hibernate.models.spi.MutableMemberDetails; import org.hibernate.models.spi.MutableMemberDetails;
import jakarta.persistence.AccessType; import jakarta.persistence.AccessType;
import jakarta.persistence.AssociationOverride;
import jakarta.persistence.AssociationOverrides;
import jakarta.persistence.AttributeOverride;
import jakarta.persistence.AttributeOverrides;
import jakarta.persistence.Column;
/** /**
* Helper for handling persistent attributes defined in mapping XML in metadata-complete mode * Helper for handling persistent attributes defined in mapping XML in metadata-complete mode
@ -208,5 +227,100 @@ public class AttributeProcessor {
memberAdjuster.adjust( memberDetails, jaxbPluralAnyMapping, xmlDocumentContext ); memberAdjuster.adjust( memberDetails, jaxbPluralAnyMapping, xmlDocumentContext );
} }
} }
for ( int i = 0; i < attributesContainer.getTransients().size(); i++ ) {
final JaxbTransientImpl jaxbTransient = attributesContainer.getTransients().get( i );
CommonAttributeProcessing.applyTransient(
jaxbTransient,
mutableClassDetails,
classAccessType,
xmlDocumentContext
);
}
}
public static void processAttributeOverrides(
List<JaxbAttributeOverrideImpl> attributeOverrides,
MutableClassDetails mutableClassDetails,
XmlDocumentContext xmlDocumentContext) {
final List<MutableAnnotationUsage<AttributeOverride>> attributeOverrideList = new ArrayList<>( attributeOverrides.size() );
for ( JaxbAttributeOverrideImpl attributeOverride : attributeOverrides ) {
final MutableAnnotationUsage<AttributeOverride> attributeOverrideAnn = XmlProcessingHelper.makeNestedAnnotation(
AttributeOverride.class,
mutableClassDetails,
xmlDocumentContext
);
attributeOverrideList.add( attributeOverrideAnn );
final MutableAnnotationUsage<Column> attributeOverrideColumnAnn = XmlProcessingHelper.makeNestedAnnotation(
Column.class,
mutableClassDetails,
xmlDocumentContext
);
ColumnProcessing.applyColumnDetails( attributeOverride.getColumn(), attributeOverrideColumnAnn, xmlDocumentContext );
attributeOverrideAnn.setAttributeValue( "name", attributeOverride.getName() );
attributeOverrideAnn.setAttributeValue( "column", attributeOverrideColumnAnn );
}
final MutableAnnotationUsage<AttributeOverrides> attributeOverridesAnn = XmlProcessingHelper.getOrMakeAnnotation(
AttributeOverrides.class,
mutableClassDetails,
xmlDocumentContext
);
attributeOverridesAnn.setAttributeValue( "value", attributeOverrideList );
}
public static void processAssociationOverrides(
List<JaxbAssociationOverrideImpl> associationOverrides,
MutableClassDetails mutableClassDetails,
XmlDocumentContext xmlDocumentContext) {
final List<MutableAnnotationUsage<AssociationOverride>> associationOverrideList = new ArrayList<>( associationOverrides.size() );
for ( JaxbAssociationOverrideImpl associationOverride : associationOverrides ) {
final MutableAnnotationUsage<AssociationOverride> attributeOverrideAnn = XmlProcessingHelper.makeNestedAnnotation(
AssociationOverride.class,
mutableClassDetails,
xmlDocumentContext
);
associationOverrideList.add( attributeOverrideAnn );
attributeOverrideAnn.setAttributeValue( "name", associationOverride.getName() );
attributeOverrideAnn.setAttributeValue(
"joinColumns",
JoinColumnProcessing.createJoinColumns(
associationOverride.getJoinColumns(),
mutableClassDetails,
xmlDocumentContext
)
);
final JaxbForeignKeyImpl foreignKeys = associationOverride.getForeignKeys();
if ( foreignKeys != null ) {
attributeOverrideAnn.setAttributeValue(
"foreignKey",
ForeignKeyProcessing.createNestedForeignKeyAnnotation(
foreignKeys,
mutableClassDetails,
xmlDocumentContext
)
);
}
final JaxbJoinTableImpl joinTable = associationOverride.getJoinTable();
if ( joinTable != null ) {
attributeOverrideAnn.setAttributeValue(
"joinTable",
TableProcessing.createNestedJoinTable(
joinTable,
mutableClassDetails,
xmlDocumentContext
)
);
}
}
final MutableAnnotationUsage<AssociationOverrides> associationOverridesAnn = XmlProcessingHelper.getOrMakeAnnotation(
AssociationOverrides.class,
mutableClassDetails,
xmlDocumentContext
);
associationOverridesAnn.setAttributeValue( "value", associationOverrideList );
} }
} }

View File

@ -29,7 +29,6 @@ import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityOrMappedSuperclass;
import org.hibernate.boot.jaxb.mapping.spi.JaxbIdImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbIdImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbManagedType; import org.hibernate.boot.jaxb.mapping.spi.JaxbManagedType;
import org.hibernate.boot.jaxb.mapping.spi.JaxbMappedSuperclassImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbMappedSuperclassImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbNamedEntityGraphImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbPersistentAttribute; import org.hibernate.boot.jaxb.mapping.spi.JaxbPersistentAttribute;
import org.hibernate.boot.jaxb.mapping.spi.JaxbTenantIdImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbTenantIdImpl;
import org.hibernate.boot.models.HibernateAnnotations; import org.hibernate.boot.models.HibernateAnnotations;
@ -154,47 +153,35 @@ public class ManagedTypeProcessor {
if ( jaxbManagedType instanceof JaxbEntityImpl jaxbDynamicEntity ) { if ( jaxbManagedType instanceof JaxbEntityImpl jaxbDynamicEntity ) {
final JaxbAttributesContainerImpl attributes = jaxbDynamicEntity.getAttributes(); final JaxbAttributesContainerImpl attributes = jaxbDynamicEntity.getAttributes();
if ( CollectionHelper.isNotEmpty( attributes.getIdAttributes() ) ) { if ( attributes != null ) {
// <id/> if ( CollectionHelper.isNotEmpty( attributes.getIdAttributes() ) ) {
attributes.getIdAttributes().forEach( (jaxbId) -> { // <id/>
final TypeDetails attributeJavaType = determineDynamicAttributeJavaType( jaxbId, xmlDocumentContext ); attributes.getIdAttributes().forEach( (jaxbId) -> {
final DynamicFieldDetails member = new DynamicFieldDetails( final TypeDetails attributeJavaType = determineDynamicAttributeJavaType(
jaxbId.getName(), jaxbId,
attributeJavaType, xmlDocumentContext
classDetails, );
MEMBER_MODIFIERS, final DynamicFieldDetails member = new DynamicFieldDetails(
false, jaxbId.getName(),
false, attributeJavaType,
xmlDocumentContext.getModelBuildingContext() classDetails,
); MEMBER_MODIFIERS,
classDetails.addField( member ); false,
} ); false,
} xmlDocumentContext.getModelBuildingContext()
else { );
// <embedded-id/> classDetails.addField( member );
final JaxbEmbeddedIdImpl embeddedId = attributes.getEmbeddedIdAttribute(); } );
final TypeDetails attributeJavaType = determineDynamicAttributeJavaType( embeddedId, xmlDocumentContext ); }
final DynamicFieldDetails member = new DynamicFieldDetails( else {
embeddedId.getName(), // <embedded-id/>
attributeJavaType, final JaxbEmbeddedIdImpl embeddedId = attributes.getEmbeddedIdAttribute();
classDetails,
MEMBER_MODIFIERS,
false,
false,
xmlDocumentContext.getModelBuildingContext()
);
classDetails.addField( member );
}
// <natural-id/>
if ( attributes.getNaturalId() != null ) {
attributes.getNaturalId().getBasicAttributes().forEach( (jaxbBasic) -> {
final TypeDetails attributeJavaType = determineDynamicAttributeJavaType( final TypeDetails attributeJavaType = determineDynamicAttributeJavaType(
jaxbBasic, embeddedId,
xmlDocumentContext xmlDocumentContext
); );
final DynamicFieldDetails member = new DynamicFieldDetails( final DynamicFieldDetails member = new DynamicFieldDetails(
jaxbBasic.getName(), embeddedId.getName(),
attributeJavaType, attributeJavaType,
classDetails, classDetails,
MEMBER_MODIFIERS, MEMBER_MODIFIERS,
@ -203,52 +190,78 @@ public class ManagedTypeProcessor {
xmlDocumentContext.getModelBuildingContext() xmlDocumentContext.getModelBuildingContext()
); );
classDetails.addField( member ); classDetails.addField( member );
} ); }
attributes.getNaturalId().getEmbeddedAttributes().forEach( (jaxbEmbedded) -> { // <natural-id/>
final TypeDetails attributeJavaType = determineDynamicAttributeJavaType( if ( attributes.getNaturalId() != null ) {
jaxbEmbedded, attributes.getNaturalId().getBasicAttributes().forEach( (jaxbBasic) -> {
xmlDocumentContext final TypeDetails attributeJavaType = determineDynamicAttributeJavaType(
); jaxbBasic,
final DynamicFieldDetails member = new DynamicFieldDetails( xmlDocumentContext
jaxbEmbedded.getName(), );
attributeJavaType, final DynamicFieldDetails member = new DynamicFieldDetails(
classDetails, jaxbBasic.getName(),
MEMBER_MODIFIERS, attributeJavaType,
false, classDetails,
false, MEMBER_MODIFIERS,
xmlDocumentContext.getModelBuildingContext() false,
); false,
classDetails.addField( member ); xmlDocumentContext.getModelBuildingContext()
} ); );
classDetails.addField( member );
} );
attributes.getNaturalId().getManyToOneAttributes().forEach( (jaxbManyToOne) -> { attributes.getNaturalId().getEmbeddedAttributes().forEach( (jaxbEmbedded) -> {
final TypeDetails attributeJavaType = determineDynamicAttributeJavaType( jaxbManyToOne, xmlDocumentContext ); final TypeDetails attributeJavaType = determineDynamicAttributeJavaType(
final DynamicFieldDetails member = new DynamicFieldDetails( jaxbEmbedded,
jaxbManyToOne.getName(), xmlDocumentContext
attributeJavaType, );
classDetails, final DynamicFieldDetails member = new DynamicFieldDetails(
MEMBER_MODIFIERS, jaxbEmbedded.getName(),
false, attributeJavaType,
false, classDetails,
xmlDocumentContext.getModelBuildingContext() MEMBER_MODIFIERS,
); false,
classDetails.addField( member ); false,
} ); xmlDocumentContext.getModelBuildingContext()
);
classDetails.addField( member );
} );
attributes.getNaturalId().getAnyMappingAttributes().forEach( (jaxbAnyMapping) -> { attributes.getNaturalId().getManyToOneAttributes().forEach( (jaxbManyToOne) -> {
final TypeDetails attributeJavaType = determineDynamicAttributeJavaType( jaxbAnyMapping, xmlDocumentContext ); final TypeDetails attributeJavaType = determineDynamicAttributeJavaType(
final DynamicFieldDetails member = new DynamicFieldDetails( jaxbManyToOne,
jaxbAnyMapping.getName(), xmlDocumentContext
attributeJavaType, );
classDetails, final DynamicFieldDetails member = new DynamicFieldDetails(
MEMBER_MODIFIERS, jaxbManyToOne.getName(),
false, attributeJavaType,
false, classDetails,
xmlDocumentContext.getModelBuildingContext() MEMBER_MODIFIERS,
); false,
classDetails.addField( member ); false,
} ); xmlDocumentContext.getModelBuildingContext()
);
classDetails.addField( member );
} );
attributes.getNaturalId().getAnyMappingAttributes().forEach( (jaxbAnyMapping) -> {
final TypeDetails attributeJavaType = determineDynamicAttributeJavaType(
jaxbAnyMapping,
xmlDocumentContext
);
final DynamicFieldDetails member = new DynamicFieldDetails(
jaxbAnyMapping.getName(),
attributeJavaType,
classDetails,
MEMBER_MODIFIERS,
false,
false,
xmlDocumentContext.getModelBuildingContext()
);
classDetails.addField( member );
} );
}
} }
// <tenant-id> // <tenant-id>
@ -273,12 +286,35 @@ public class ManagedTypeProcessor {
else if ( jaxbManagedType instanceof JaxbMappedSuperclassImpl jaxbMappedSuperclass ) { else if ( jaxbManagedType instanceof JaxbMappedSuperclassImpl jaxbMappedSuperclass ) {
final JaxbAttributesContainerImpl attributes = jaxbMappedSuperclass.getAttributes(); final JaxbAttributesContainerImpl attributes = jaxbMappedSuperclass.getAttributes();
if ( CollectionHelper.isNotEmpty( attributes.getIdAttributes() ) ) { if ( attributes != null ) {
// <id/> if ( CollectionHelper.isNotEmpty( attributes.getIdAttributes() ) ) {
attributes.getIdAttributes().forEach( (jaxbId) -> { // <id/>
final TypeDetails attributeJavaType = determineDynamicAttributeJavaType( jaxbId, xmlDocumentContext ); attributes.getIdAttributes().forEach( (jaxbId) -> {
final TypeDetails attributeJavaType = determineDynamicAttributeJavaType(
jaxbId,
xmlDocumentContext
);
final DynamicFieldDetails member = new DynamicFieldDetails(
jaxbId.getName(),
attributeJavaType,
classDetails,
MEMBER_MODIFIERS,
false,
false,
xmlDocumentContext.getModelBuildingContext()
);
classDetails.addField( member );
} );
}
else {
// <embedded-id/>
final JaxbEmbeddedIdImpl embeddedId = attributes.getEmbeddedIdAttribute();
final TypeDetails attributeJavaType = determineDynamicAttributeJavaType(
embeddedId,
xmlDocumentContext
);
final DynamicFieldDetails member = new DynamicFieldDetails( final DynamicFieldDetails member = new DynamicFieldDetails(
jaxbId.getName(), embeddedId.getName(),
attributeJavaType, attributeJavaType,
classDetails, classDetails,
MEMBER_MODIFIERS, MEMBER_MODIFIERS,
@ -287,15 +323,18 @@ public class ManagedTypeProcessor {
xmlDocumentContext.getModelBuildingContext() xmlDocumentContext.getModelBuildingContext()
); );
classDetails.addField( member ); classDetails.addField( member );
} ); }
} }
else { }
// <embedded-id/>
final JaxbEmbeddedIdImpl embeddedId = attributes.getEmbeddedIdAttribute(); final JaxbAttributesContainer attributes = jaxbManagedType.getAttributes();
final TypeDetails attributeJavaType = determineDynamicAttributeJavaType( embeddedId, xmlDocumentContext );
if ( attributes != null ) {
// <basic/>
attributes.getBasicAttributes().forEach( (jaxbBasic) -> {
final DynamicFieldDetails member = new DynamicFieldDetails( final DynamicFieldDetails member = new DynamicFieldDetails(
embeddedId.getName(), jaxbBasic.getName(),
attributeJavaType, determineDynamicAttributeJavaType( jaxbBasic, xmlDocumentContext ),
classDetails, classDetails,
MEMBER_MODIFIERS, MEMBER_MODIFIERS,
false, false,
@ -303,140 +342,124 @@ public class ManagedTypeProcessor {
xmlDocumentContext.getModelBuildingContext() xmlDocumentContext.getModelBuildingContext()
); );
classDetails.addField( member ); classDetails.addField( member );
} } );
// <embedded/>
attributes.getEmbeddedAttributes().forEach( (jaxbEmbedded) -> {
final DynamicFieldDetails member = new DynamicFieldDetails(
jaxbEmbedded.getName(),
determineDynamicAttributeJavaType( jaxbEmbedded, xmlDocumentContext ),
classDetails,
MEMBER_MODIFIERS,
false,
false,
xmlDocumentContext.getModelBuildingContext()
);
classDetails.addField( member );
} );
// <one-to-one/>
attributes.getOneToOneAttributes().forEach( (jaxbOneToOne) -> {
final DynamicFieldDetails member = new DynamicFieldDetails(
jaxbOneToOne.getName(),
determineDynamicAttributeJavaType( jaxbOneToOne, xmlDocumentContext ),
classDetails,
MEMBER_MODIFIERS,
false,
false,
xmlDocumentContext.getModelBuildingContext()
);
classDetails.addField( member );
} );
// <many-to-one/>
attributes.getManyToOneAttributes().forEach( (jaxbManyToOne) -> {
final DynamicFieldDetails member = new DynamicFieldDetails(
jaxbManyToOne.getName(),
determineDynamicAttributeJavaType( jaxbManyToOne, xmlDocumentContext ),
classDetails,
MEMBER_MODIFIERS,
false,
false,
xmlDocumentContext.getModelBuildingContext()
);
classDetails.addField( member );
} );
// <any/>
attributes.getAnyMappingAttributes().forEach( (jaxbAnyMapping) -> {
final DynamicFieldDetails member = new DynamicFieldDetails(
jaxbAnyMapping.getName(),
determineDynamicAttributeJavaType( jaxbAnyMapping, xmlDocumentContext ),
classDetails,
MEMBER_MODIFIERS,
false,
false,
xmlDocumentContext.getModelBuildingContext()
);
classDetails.addField( member );
} );
// <element-collection/>
attributes.getElementCollectionAttributes().forEach( (jaxbElementCollection) -> {
final DynamicFieldDetails member = new DynamicFieldDetails(
jaxbElementCollection.getName(),
determineDynamicAttributeJavaType( jaxbElementCollection, xmlDocumentContext ),
classDetails,
MEMBER_MODIFIERS,
false,
true,
xmlDocumentContext.getModelBuildingContext()
);
classDetails.addField( member );
} );
// <one-to-many/>
attributes.getOneToManyAttributes().forEach( (jaxbOneToMany) -> {
final DynamicFieldDetails member = new DynamicFieldDetails(
jaxbOneToMany.getName(),
determineDynamicAttributeJavaType( jaxbOneToMany, xmlDocumentContext ),
classDetails,
MEMBER_MODIFIERS,
false,
true,
xmlDocumentContext.getModelBuildingContext()
);
classDetails.addField( member );
} );
// <many-to-many/>
attributes.getManyToManyAttributes().forEach( (jaxbManyToMany) -> {
final DynamicFieldDetails member = new DynamicFieldDetails(
jaxbManyToMany.getName(),
determineDynamicAttributeJavaType( jaxbManyToMany, xmlDocumentContext ),
classDetails,
MEMBER_MODIFIERS,
false,
true,
xmlDocumentContext.getModelBuildingContext()
);
classDetails.addField( member );
} );
// <many-to-any/>
attributes.getPluralAnyMappingAttributes().forEach( (jaxbPluralAnyMapping) -> {
final TypeDetails attributeType = determineDynamicAttributeJavaType(
jaxbPluralAnyMapping,
xmlDocumentContext
);
final DynamicFieldDetails member = new DynamicFieldDetails(
jaxbPluralAnyMapping.getName(),
attributeType,
classDetails,
MEMBER_MODIFIERS,
false,
true,
xmlDocumentContext.getModelBuildingContext()
);
classDetails.addField( member );
} );
} }
final JaxbAttributesContainer attributes = jaxbManagedType.getAttributes();
// <basic/>
attributes.getBasicAttributes().forEach( (jaxbBasic) -> {
final DynamicFieldDetails member = new DynamicFieldDetails(
jaxbBasic.getName(),
determineDynamicAttributeJavaType( jaxbBasic, xmlDocumentContext ),
classDetails,
MEMBER_MODIFIERS,
false,
false,
xmlDocumentContext.getModelBuildingContext()
);
classDetails.addField( member );
} );
// <embedded/>
attributes.getEmbeddedAttributes().forEach( (jaxbEmbedded) -> {
final DynamicFieldDetails member = new DynamicFieldDetails(
jaxbEmbedded.getName(),
determineDynamicAttributeJavaType( jaxbEmbedded, xmlDocumentContext ),
classDetails,
MEMBER_MODIFIERS,
false,
false,
xmlDocumentContext.getModelBuildingContext()
);
classDetails.addField( member );
} );
// <one-to-one/>
attributes.getOneToOneAttributes().forEach( (jaxbOneToOne) -> {
final DynamicFieldDetails member = new DynamicFieldDetails(
jaxbOneToOne.getName(),
determineDynamicAttributeJavaType( jaxbOneToOne, xmlDocumentContext ),
classDetails,
MEMBER_MODIFIERS,
false,
false,
xmlDocumentContext.getModelBuildingContext()
);
classDetails.addField( member );
} );
// <many-to-one/>
attributes.getManyToOneAttributes().forEach( (jaxbManyToOne) -> {
final DynamicFieldDetails member = new DynamicFieldDetails(
jaxbManyToOne.getName(),
determineDynamicAttributeJavaType( jaxbManyToOne, xmlDocumentContext ),
classDetails,
MEMBER_MODIFIERS,
false,
false,
xmlDocumentContext.getModelBuildingContext()
);
classDetails.addField( member );
} );
// <any/>
attributes.getAnyMappingAttributes().forEach( (jaxbAnyMapping) -> {
final DynamicFieldDetails member = new DynamicFieldDetails(
jaxbAnyMapping.getName(),
determineDynamicAttributeJavaType( jaxbAnyMapping, xmlDocumentContext ),
classDetails,
MEMBER_MODIFIERS,
false,
false,
xmlDocumentContext.getModelBuildingContext()
);
classDetails.addField( member );
} );
// <element-collection/>
attributes.getElementCollectionAttributes().forEach( (jaxbElementCollection) -> {
final DynamicFieldDetails member = new DynamicFieldDetails(
jaxbElementCollection.getName(),
determineDynamicAttributeJavaType( jaxbElementCollection, xmlDocumentContext ),
classDetails,
MEMBER_MODIFIERS,
false,
true,
xmlDocumentContext.getModelBuildingContext()
);
classDetails.addField( member );
} );
// <one-to-many/>
attributes.getOneToManyAttributes().forEach( (jaxbOneToMany) -> {
final DynamicFieldDetails member = new DynamicFieldDetails(
jaxbOneToMany.getName(),
determineDynamicAttributeJavaType( jaxbOneToMany, xmlDocumentContext ),
classDetails,
MEMBER_MODIFIERS,
false,
true,
xmlDocumentContext.getModelBuildingContext()
);
classDetails.addField( member );
} );
// <many-to-many/>
attributes.getManyToManyAttributes().forEach( (jaxbManyToMany) -> {
final DynamicFieldDetails member = new DynamicFieldDetails(
jaxbManyToMany.getName(),
determineDynamicAttributeJavaType( jaxbManyToMany, xmlDocumentContext ),
classDetails,
MEMBER_MODIFIERS,
false,
true,
xmlDocumentContext.getModelBuildingContext()
);
classDetails.addField( member );
} );
// <many-to-any/>
attributes.getPluralAnyMappingAttributes().forEach( (jaxbPluralAnyMapping) -> {
final TypeDetails attributeType = determineDynamicAttributeJavaType(
jaxbPluralAnyMapping,
xmlDocumentContext
);
final DynamicFieldDetails member = new DynamicFieldDetails(
jaxbPluralAnyMapping.getName(),
attributeType,
classDetails,
MEMBER_MODIFIERS,
false,
true,
xmlDocumentContext.getModelBuildingContext()
);
classDetails.addField( member );
} );
} }
private static TypeDetails determineDynamicAttributeJavaType( private static TypeDetails determineDynamicAttributeJavaType(
@ -503,6 +526,16 @@ public class ManagedTypeProcessor {
xmlDocumentContext xmlDocumentContext
); );
} }
AttributeProcessor.processAttributeOverrides(
jaxbEntity.getAttributeOverrides(),
classDetails,
xmlDocumentContext
);
AttributeProcessor.processAssociationOverrides(
jaxbEntity.getAssociationOverrides(),
classDetails,
xmlDocumentContext
);
QueryProcessing.applyNamedQueries( jaxbEntity, classDetails, xmlDocumentContext ); QueryProcessing.applyNamedQueries( jaxbEntity, classDetails, xmlDocumentContext );
QueryProcessing.applyNamedNativeQueries( jaxbEntity, classDetails, jaxbRoot, xmlDocumentContext ); QueryProcessing.applyNamedNativeQueries( jaxbEntity, classDetails, jaxbRoot, xmlDocumentContext );
@ -779,17 +812,25 @@ public class ManagedTypeProcessor {
jaxbMappedSuperclass.getAccess(), jaxbMappedSuperclass.getAccess(),
xmlDocumentContext.getEffectiveDefaults().getDefaultPropertyAccessType() xmlDocumentContext.getEffectiveDefaults().getDefaultPropertyAccessType()
); );
classDetails.addAnnotationUsage( XmlAnnotationHelper.createAccessAnnotation( classAccessType, classDetails, xmlDocumentContext ) ); if ( classAccessType != null ) {
classDetails.addAnnotationUsage( XmlAnnotationHelper.createAccessAnnotation(
classAccessType,
classDetails,
xmlDocumentContext
) );
}
final JaxbAttributesContainerImpl attributes = jaxbMappedSuperclass.getAttributes(); final JaxbAttributesContainerImpl attributes = jaxbMappedSuperclass.getAttributes();
processIdMappings( if ( attributes != null ) {
attributes, processIdMappings(
classAccessType, attributes,
classDetails, classAccessType,
ManagedTypeProcessor::adjustNonDynamicTypeMember, classDetails,
xmlDocumentContext ManagedTypeProcessor::adjustNonDynamicTypeMember,
); xmlDocumentContext
AttributeProcessor.processAttributes( attributes, classDetails, classAccessType, xmlDocumentContext ); );
AttributeProcessor.processAttributes( attributes, classDetails, classAccessType, xmlDocumentContext );
}
processEntityOrMappedSuperclass( jaxbMappedSuperclass, classDetails, xmlDocumentContext ); processEntityOrMappedSuperclass( jaxbMappedSuperclass, classDetails, xmlDocumentContext );
} }
@ -882,15 +923,22 @@ public class ManagedTypeProcessor {
AttributeProcessor.MemberAdjuster memberAdjuster, AttributeProcessor.MemberAdjuster memberAdjuster,
XmlDocumentContext xmlDocumentContext) { XmlDocumentContext xmlDocumentContext) {
XmlProcessingHelper.getOrMakeAnnotation( Embeddable.class, classDetails, xmlDocumentContext ); XmlProcessingHelper.getOrMakeAnnotation( Embeddable.class, classDetails, xmlDocumentContext );
classDetails.addAnnotationUsage( XmlAnnotationHelper.createAccessAnnotation( classAccessType, classDetails, xmlDocumentContext ) ); if ( classAccessType != null ) {
classDetails.addAnnotationUsage( XmlAnnotationHelper.createAccessAnnotation(
AttributeProcessor.processAttributes( classAccessType,
jaxbEmbeddable.getAttributes(), classDetails,
classDetails, xmlDocumentContext
AccessType.FIELD, ) );
memberAdjuster, }
xmlDocumentContext if ( jaxbEmbeddable.getAttributes() != null ) {
); AttributeProcessor.processAttributes(
jaxbEmbeddable.getAttributes(),
classDetails,
AccessType.FIELD,
memberAdjuster,
xmlDocumentContext
);
}
} }
public static void processOverrideEmbeddable(List<XmlProcessingResult.OverrideTuple<JaxbEmbeddableImpl>> embeddableOverrides) { public static void processOverrideEmbeddable(List<XmlProcessingResult.OverrideTuple<JaxbEmbeddableImpl>> embeddableOverrides) {
@ -906,13 +954,15 @@ public class ManagedTypeProcessor {
XmlProcessingHelper.getOrMakeAnnotation( Embeddable.class, classDetails, xmlDocumentContext ); XmlProcessingHelper.getOrMakeAnnotation( Embeddable.class, classDetails, xmlDocumentContext );
AttributeProcessor.processAttributes( if ( jaxbEmbeddable.getAttributes() != null ) {
jaxbEmbeddable.getAttributes(), AttributeProcessor.processAttributes(
classDetails, jaxbEmbeddable.getAttributes(),
AccessType.FIELD, classDetails,
ManagedTypeProcessor::adjustNonDynamicTypeMember, AccessType.FIELD,
xmlDocumentContext ManagedTypeProcessor::adjustNonDynamicTypeMember,
); xmlDocumentContext
);
}
} ); } );
} }

View File

@ -97,6 +97,7 @@ import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.models.ModelsException; import org.hibernate.models.ModelsException;
import org.hibernate.models.spi.AnnotationDescriptor; import org.hibernate.models.spi.AnnotationDescriptor;
import org.hibernate.models.spi.AnnotationTarget;
import org.hibernate.models.spi.AnnotationUsage; import org.hibernate.models.spi.AnnotationUsage;
import org.hibernate.models.spi.ClassDetails; import org.hibernate.models.spi.ClassDetails;
import org.hibernate.models.spi.ClassDetailsRegistry; import org.hibernate.models.spi.ClassDetailsRegistry;
@ -144,6 +145,7 @@ import jakarta.persistence.TableGenerator;
import jakarta.persistence.Temporal; import jakarta.persistence.Temporal;
import jakarta.persistence.TemporalType; import jakarta.persistence.TemporalType;
import jakarta.persistence.UniqueConstraint; import jakarta.persistence.UniqueConstraint;
import org.checkerframework.checker.nullness.qual.Nullable;
import static java.lang.Boolean.FALSE; import static java.lang.Boolean.FALSE;
import static java.util.Collections.emptyList; import static java.util.Collections.emptyList;
@ -420,7 +422,7 @@ public class XmlAnnotationHelper {
public static <A extends Annotation> void applyUniqueConstraints( public static <A extends Annotation> void applyUniqueConstraints(
List<JaxbUniqueConstraintImpl> jaxbUniqueConstraints, List<JaxbUniqueConstraintImpl> jaxbUniqueConstraints,
MutableAnnotationTarget target, AnnotationTarget target,
MutableAnnotationUsage<A> annotationUsage, MutableAnnotationUsage<A> annotationUsage,
XmlDocumentContext xmlDocumentContext) { XmlDocumentContext xmlDocumentContext) {
if ( CollectionHelper.isEmpty( jaxbUniqueConstraints ) ) { if ( CollectionHelper.isEmpty( jaxbUniqueConstraints ) ) {
@ -444,7 +446,7 @@ public class XmlAnnotationHelper {
public static <A extends Annotation> void applyIndexes( public static <A extends Annotation> void applyIndexes(
List<JaxbIndexImpl> jaxbIndexes, List<JaxbIndexImpl> jaxbIndexes,
MutableAnnotationTarget target, AnnotationTarget target,
MutableAnnotationUsage<A> annotationUsage, MutableAnnotationUsage<A> annotationUsage,
XmlDocumentContext xmlDocumentContext) { XmlDocumentContext xmlDocumentContext) {
if ( CollectionHelper.isEmpty( jaxbIndexes ) ) { if ( CollectionHelper.isEmpty( jaxbIndexes ) ) {
@ -471,7 +473,7 @@ public class XmlAnnotationHelper {
public static <A extends Annotation> void applyCheckConstraints( public static <A extends Annotation> void applyCheckConstraints(
JaxbCheckable jaxbCheckable, JaxbCheckable jaxbCheckable,
MutableAnnotationTarget target, AnnotationTarget target,
MutableAnnotationUsage<A> annotationUsage, MutableAnnotationUsage<A> annotationUsage,
XmlDocumentContext xmlDocumentContext) { XmlDocumentContext xmlDocumentContext) {
if ( jaxbCheckable!= null && CollectionHelper.isNotEmpty( jaxbCheckable.getCheckConstraints() ) ) { if ( jaxbCheckable!= null && CollectionHelper.isNotEmpty( jaxbCheckable.getCheckConstraints() ) ) {
@ -480,7 +482,7 @@ public class XmlAnnotationHelper {
.getAnnotationDescriptorRegistry() .getAnnotationDescriptorRegistry()
.getDescriptor( CheckConstraint.class ); .getDescriptor( CheckConstraint.class );
for ( JaxbCheckConstraintImpl jaxbCheck : jaxbCheckable.getCheckConstraints() ) { for ( JaxbCheckConstraintImpl jaxbCheck : jaxbCheckable.getCheckConstraints() ) {
final MutableAnnotationUsage<CheckConstraint> checkAnn = XmlProcessingHelper.getOrMakeAnnotation( CheckConstraint.class, target, xmlDocumentContext ); final MutableAnnotationUsage<CheckConstraint> checkAnn = XmlProcessingHelper.makeNestedAnnotation( CheckConstraint.class, target, xmlDocumentContext );
applyOr( jaxbCheck, JaxbCheckConstraintImpl::getName, "name", checkAnn, checkConstraintDescriptor ); applyOr( jaxbCheck, JaxbCheckConstraintImpl::getName, "name", checkAnn, checkConstraintDescriptor );
applyOr( jaxbCheck, JaxbCheckConstraintImpl::getConstraint, "constraint", checkAnn, checkConstraintDescriptor ); applyOr( jaxbCheck, JaxbCheckConstraintImpl::getConstraint, "constraint", checkAnn, checkConstraintDescriptor );
applyOr( jaxbCheck, JaxbCheckConstraintImpl::getOptions, "options", checkAnn, checkConstraintDescriptor ); applyOr( jaxbCheck, JaxbCheckConstraintImpl::getOptions, "options", checkAnn, checkConstraintDescriptor );
@ -959,7 +961,7 @@ public class XmlAnnotationHelper {
public static <A extends Annotation> void applyTableAttributes( public static <A extends Annotation> void applyTableAttributes(
JaxbTableMapping jaxbTable, JaxbTableMapping jaxbTable,
MutableAnnotationTarget target, AnnotationTarget target,
MutableAnnotationUsage<A> tableAnn, MutableAnnotationUsage<A> tableAnn,
AnnotationDescriptor<A> annotationDescriptor, AnnotationDescriptor<A> annotationDescriptor,
XmlDocumentContext xmlDocumentContext) { XmlDocumentContext xmlDocumentContext) {
@ -1498,7 +1500,7 @@ public class XmlAnnotationHelper {
} }
public static void applyDiscriminatorFormula( public static void applyDiscriminatorFormula(
JaxbDiscriminatorFormulaImpl jaxbDiscriminatorFormula, @Nullable JaxbDiscriminatorFormulaImpl jaxbDiscriminatorFormula,
MutableClassDetails target, MutableClassDetails target,
XmlDocumentContext xmlDocumentContext) { XmlDocumentContext xmlDocumentContext) {
if ( jaxbDiscriminatorFormula == null ) { if ( jaxbDiscriminatorFormula == null ) {

View File

@ -16,6 +16,7 @@ import org.hibernate.boot.models.internal.AnnotationUsageHelper;
import org.hibernate.boot.models.xml.spi.XmlDocumentContext; import org.hibernate.boot.models.xml.spi.XmlDocumentContext;
import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.StringHelper;
import org.hibernate.models.internal.dynamic.DynamicAnnotationUsage; import org.hibernate.models.internal.dynamic.DynamicAnnotationUsage;
import org.hibernate.models.spi.AnnotationTarget;
import org.hibernate.models.spi.AnnotationUsage; import org.hibernate.models.spi.AnnotationUsage;
import org.hibernate.models.spi.FieldDetails; import org.hibernate.models.spi.FieldDetails;
import org.hibernate.models.spi.MethodDetails; import org.hibernate.models.spi.MethodDetails;
@ -139,7 +140,7 @@ public class XmlProcessingHelper {
*/ */
public static <A extends Annotation> MutableAnnotationUsage<A> makeNestedAnnotation( public static <A extends Annotation> MutableAnnotationUsage<A> makeNestedAnnotation(
Class<A> annotationType, Class<A> annotationType,
MutableAnnotationTarget target, AnnotationTarget target,
XmlDocumentContext xmlDocumentContext) { XmlDocumentContext xmlDocumentContext) {
return new DynamicAnnotationUsage<>( return new DynamicAnnotationUsage<>(
xmlDocumentContext.getModelBuildingContext() xmlDocumentContext.getModelBuildingContext()

View File

@ -18,15 +18,20 @@ import org.hibernate.boot.jaxb.mapping.spi.JaxbPersistentAttribute;
import org.hibernate.boot.jaxb.mapping.spi.JaxbSingularAssociationAttribute; import org.hibernate.boot.jaxb.mapping.spi.JaxbSingularAssociationAttribute;
import org.hibernate.boot.jaxb.mapping.spi.JaxbSingularFetchModeImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbSingularFetchModeImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbStandardAttribute; import org.hibernate.boot.jaxb.mapping.spi.JaxbStandardAttribute;
import org.hibernate.boot.jaxb.mapping.spi.JaxbTransientImpl;
import org.hibernate.boot.models.xml.internal.XmlProcessingHelper; import org.hibernate.boot.models.xml.internal.XmlProcessingHelper;
import org.hibernate.boot.models.xml.spi.XmlDocumentContext; import org.hibernate.boot.models.xml.spi.XmlDocumentContext;
import org.hibernate.models.spi.ClassDetails; import org.hibernate.models.spi.ClassDetails;
import org.hibernate.models.spi.MutableAnnotationUsage; import org.hibernate.models.spi.MutableAnnotationUsage;
import org.hibernate.models.spi.MutableClassDetails;
import org.hibernate.models.spi.MutableMemberDetails; import org.hibernate.models.spi.MutableMemberDetails;
import jakarta.persistence.Access; import jakarta.persistence.Access;
import jakarta.persistence.AccessType; import jakarta.persistence.AccessType;
import jakarta.persistence.FetchType; import jakarta.persistence.FetchType;
import jakarta.persistence.Transient;
import static org.hibernate.internal.util.NullnessHelper.coalesce;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
@ -127,4 +132,17 @@ public class CommonAttributeProcessing {
fetchAnn.setAttributeValue( "value", fetchMode ); fetchAnn.setAttributeValue( "value", fetchMode );
} }
} }
public static void applyTransient(
JaxbTransientImpl jaxbTransient,
MutableClassDetails declarer,
AccessType classAccessType,
XmlDocumentContext xmlDocumentContext) {
final MutableMemberDetails memberDetails = XmlProcessingHelper.getAttributeMember(
jaxbTransient.getName(),
classAccessType,
declarer
);
XmlProcessingHelper.makeAnnotation( Transient.class, memberDetails, xmlDocumentContext );
}
} }

View File

@ -102,7 +102,7 @@ public class ManyToManyAttributeProcessing {
"targetEntity", "targetEntity",
xmlDocumentContext.getModelBuildingContext() xmlDocumentContext.getModelBuildingContext()
.getClassDetailsRegistry() .getClassDetailsRegistry()
.resolveClassDetails( targetEntity ) .resolveClassDetails( xmlDocumentContext.resolveClassName( targetEntity ) )
); );
} }
} }

View File

@ -23,6 +23,7 @@ import org.hibernate.boot.models.internal.AnnotationUsageHelper;
import org.hibernate.boot.models.xml.internal.XmlAnnotationHelper; import org.hibernate.boot.models.xml.internal.XmlAnnotationHelper;
import org.hibernate.boot.models.xml.internal.XmlProcessingHelper; import org.hibernate.boot.models.xml.internal.XmlProcessingHelper;
import org.hibernate.boot.models.xml.spi.XmlDocumentContext; import org.hibernate.boot.models.xml.spi.XmlDocumentContext;
import org.hibernate.models.spi.AnnotationTarget;
import org.hibernate.models.spi.MutableAnnotationTarget; import org.hibernate.models.spi.MutableAnnotationTarget;
import org.hibernate.models.spi.MutableAnnotationUsage; import org.hibernate.models.spi.MutableAnnotationUsage;
import org.hibernate.models.spi.MutableMemberDetails; import org.hibernate.models.spi.MutableMemberDetails;
@ -36,7 +37,7 @@ public class ColumnProcessing {
public static <A extends Annotation> void applyColumnDetails( public static <A extends Annotation> void applyColumnDetails(
JaxbColumnCommon jaxbColumn, JaxbColumnCommon jaxbColumn,
MutableAnnotationTarget target, AnnotationTarget target,
MutableAnnotationUsage<A> columnAnn, MutableAnnotationUsage<A> columnAnn,
XmlDocumentContext xmlDocumentContext) { XmlDocumentContext xmlDocumentContext) {
if ( jaxbColumn == null ) { if ( jaxbColumn == null ) {
@ -98,7 +99,7 @@ public class ColumnProcessing {
public static <A extends Annotation> void applyColumnDetails( public static <A extends Annotation> void applyColumnDetails(
JaxbColumn jaxbColumn, JaxbColumn jaxbColumn,
MutableAnnotationTarget target, AnnotationTarget target,
MutableAnnotationUsage<A> columnAnn, MutableAnnotationUsage<A> columnAnn,
XmlDocumentContext xmlDocumentContext) { XmlDocumentContext xmlDocumentContext) {
if ( jaxbColumn == null ) { if ( jaxbColumn == null ) {
@ -170,6 +171,8 @@ public class ColumnProcessing {
XmlProcessingHelper.applyAttributeIfSpecified( "precision", jaxbColumn.getPrecision(), columnAnn ); XmlProcessingHelper.applyAttributeIfSpecified( "precision", jaxbColumn.getPrecision(), columnAnn );
XmlProcessingHelper.applyAttributeIfSpecified( "scale", jaxbColumn.getScale(), columnAnn ); XmlProcessingHelper.applyAttributeIfSpecified( "scale", jaxbColumn.getScale(), columnAnn );
XmlProcessingHelper.applyAttributeIfSpecified( "secondPrecision", jaxbColumn.getSecondPrecision(), columnAnn );
} }
private static <A extends Annotation> void applyColumnUniqueness( private static <A extends Annotation> void applyColumnUniqueness(

View File

@ -10,6 +10,7 @@ import org.hibernate.boot.jaxb.mapping.spi.JaxbForeignKeyImpl;
import org.hibernate.boot.models.JpaAnnotations; import org.hibernate.boot.models.JpaAnnotations;
import org.hibernate.boot.models.xml.internal.XmlAnnotationHelper; import org.hibernate.boot.models.xml.internal.XmlAnnotationHelper;
import org.hibernate.boot.models.xml.spi.XmlDocumentContext; import org.hibernate.boot.models.xml.spi.XmlDocumentContext;
import org.hibernate.models.spi.AnnotationTarget;
import org.hibernate.models.spi.MemberDetails; import org.hibernate.models.spi.MemberDetails;
import org.hibernate.models.spi.MutableAnnotationUsage; import org.hibernate.models.spi.MutableAnnotationUsage;
import org.hibernate.models.spi.MutableMemberDetails; import org.hibernate.models.spi.MutableMemberDetails;
@ -53,12 +54,12 @@ public class ForeignKeyProcessing {
public static MutableAnnotationUsage<ForeignKey> createNestedForeignKeyAnnotation( public static MutableAnnotationUsage<ForeignKey> createNestedForeignKeyAnnotation(
JaxbForeignKeyImpl jaxbForeignKey, JaxbForeignKeyImpl jaxbForeignKey,
MemberDetails memberDetails, AnnotationTarget annotationTarget,
XmlDocumentContext xmlDocumentContext) { XmlDocumentContext xmlDocumentContext) {
assert jaxbForeignKey != null; assert jaxbForeignKey != null;
final MutableAnnotationUsage<ForeignKey> foreignKeyUsage = JpaAnnotations.FOREIGN_KEY.createUsage( final MutableAnnotationUsage<ForeignKey> foreignKeyUsage = JpaAnnotations.FOREIGN_KEY.createUsage(
memberDetails, annotationTarget,
xmlDocumentContext.getModelBuildingContext() xmlDocumentContext.getModelBuildingContext()
); );

View File

@ -21,7 +21,9 @@ import org.hibernate.boot.models.xml.internal.XmlAnnotationHelper;
import org.hibernate.boot.models.xml.internal.XmlProcessingHelper; import org.hibernate.boot.models.xml.internal.XmlProcessingHelper;
import org.hibernate.boot.models.xml.spi.XmlDocumentContext; import org.hibernate.boot.models.xml.spi.XmlDocumentContext;
import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.models.spi.AnnotationTarget;
import org.hibernate.models.spi.AnnotationUsage; import org.hibernate.models.spi.AnnotationUsage;
import org.hibernate.models.spi.MutableAnnotationTarget;
import org.hibernate.models.spi.MutableAnnotationUsage; import org.hibernate.models.spi.MutableAnnotationUsage;
import org.hibernate.models.spi.MutableMemberDetails; import org.hibernate.models.spi.MutableMemberDetails;
@ -117,9 +119,9 @@ public class JoinColumnProcessing {
public static void transferJoinColumn( public static void transferJoinColumn(
JaxbColumnJoined jaxbJoinColumn, JaxbColumnJoined jaxbJoinColumn,
MutableAnnotationUsage<? extends Annotation> joinColumnUsage, MutableAnnotationUsage<? extends Annotation> joinColumnUsage,
MutableMemberDetails memberDetails, AnnotationTarget annotationTarget,
XmlDocumentContext xmlDocumentContext) { XmlDocumentContext xmlDocumentContext) {
ColumnProcessing.applyColumnDetails( jaxbJoinColumn, memberDetails, joinColumnUsage, xmlDocumentContext ); ColumnProcessing.applyColumnDetails( jaxbJoinColumn, annotationTarget, joinColumnUsage, xmlDocumentContext );
XmlAnnotationHelper.applyOptionalAttribute( XmlAnnotationHelper.applyOptionalAttribute(
joinColumnUsage, joinColumnUsage,
"referencedColumnName", "referencedColumnName",
@ -130,7 +132,7 @@ public class JoinColumnProcessing {
if ( jaxbForeignKey != null ) { if ( jaxbForeignKey != null ) {
joinColumnUsage.setAttributeValue( joinColumnUsage.setAttributeValue(
"foreignKey", "foreignKey",
ForeignKeyProcessing.createNestedForeignKeyAnnotation( jaxbForeignKey, memberDetails, xmlDocumentContext ) ForeignKeyProcessing.createNestedForeignKeyAnnotation( jaxbForeignKey, annotationTarget, xmlDocumentContext )
); );
} }
} }
@ -143,7 +145,7 @@ public class JoinColumnProcessing {
*/ */
public static List<AnnotationUsage<JoinColumn>> transformJoinColumnList( public static List<AnnotationUsage<JoinColumn>> transformJoinColumnList(
List<JaxbJoinColumnImpl> jaxbJoinColumns, List<JaxbJoinColumnImpl> jaxbJoinColumns,
MutableMemberDetails memberDetails, AnnotationTarget annotationTarget,
XmlDocumentContext xmlDocumentContext) { XmlDocumentContext xmlDocumentContext) {
if ( CollectionHelper.isEmpty( jaxbJoinColumns ) ) { if ( CollectionHelper.isEmpty( jaxbJoinColumns ) ) {
return Collections.emptyList(); return Collections.emptyList();
@ -151,7 +153,7 @@ public class JoinColumnProcessing {
final List<AnnotationUsage<JoinColumn>> joinColumns = new ArrayList<>( jaxbJoinColumns.size() ); final List<AnnotationUsage<JoinColumn>> joinColumns = new ArrayList<>( jaxbJoinColumns.size() );
jaxbJoinColumns.forEach( jaxbJoinColumn -> { jaxbJoinColumns.forEach( jaxbJoinColumn -> {
final MutableAnnotationUsage<JoinColumn> joinColumnAnn = JpaAnnotations.JOIN_COLUMN.createUsage( final MutableAnnotationUsage<JoinColumn> joinColumnAnn = JpaAnnotations.JOIN_COLUMN.createUsage(
memberDetails, annotationTarget,
xmlDocumentContext.getModelBuildingContext() xmlDocumentContext.getModelBuildingContext()
); );
transferJoinColumn( jaxbJoinColumn, joinColumnAnn, null, xmlDocumentContext ); transferJoinColumn( jaxbJoinColumn, joinColumnAnn, null, xmlDocumentContext );
@ -177,7 +179,7 @@ public class JoinColumnProcessing {
public static List<AnnotationUsage<JoinColumn>> createJoinColumns( public static List<AnnotationUsage<JoinColumn>> createJoinColumns(
List<JaxbJoinColumnImpl> jaxbJoinColumns, List<JaxbJoinColumnImpl> jaxbJoinColumns,
MutableMemberDetails memberDetails, AnnotationTarget annotationTarget,
XmlDocumentContext xmlDocumentContext) { XmlDocumentContext xmlDocumentContext) {
if ( CollectionHelper.isEmpty( jaxbJoinColumns ) ) { if ( CollectionHelper.isEmpty( jaxbJoinColumns ) ) {
return Collections.emptyList(); return Collections.emptyList();
@ -185,13 +187,13 @@ public class JoinColumnProcessing {
final List<AnnotationUsage<JoinColumn>> joinColumns = new ArrayList<>( jaxbJoinColumns.size() ); final List<AnnotationUsage<JoinColumn>> joinColumns = new ArrayList<>( jaxbJoinColumns.size() );
jaxbJoinColumns.forEach( jaxbJoinColumn -> { jaxbJoinColumns.forEach( jaxbJoinColumn -> {
final MutableAnnotationUsage<JoinColumn> joinColumnUsage = JpaAnnotations.JOIN_COLUMN.createUsage( final MutableAnnotationUsage<JoinColumn> joinColumnUsage = JpaAnnotations.JOIN_COLUMN.createUsage(
memberDetails, annotationTarget,
xmlDocumentContext.getModelBuildingContext() xmlDocumentContext.getModelBuildingContext()
); );
transferJoinColumn( transferJoinColumn(
jaxbJoinColumn, jaxbJoinColumn,
joinColumnUsage, joinColumnUsage,
memberDetails, annotationTarget,
xmlDocumentContext xmlDocumentContext
); );
joinColumns.add( joinColumnUsage ); joinColumns.add( joinColumnUsage );

View File

@ -12,11 +12,14 @@ import org.hibernate.boot.jaxb.mapping.spi.JaxbJoinColumnImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbJoinTableImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbJoinTableImpl;
import org.hibernate.boot.models.JpaAnnotations; import org.hibernate.boot.models.JpaAnnotations;
import org.hibernate.boot.models.xml.internal.XmlAnnotationHelper; import org.hibernate.boot.models.xml.internal.XmlAnnotationHelper;
import org.hibernate.boot.models.xml.internal.XmlProcessingHelper;
import org.hibernate.boot.models.xml.spi.XmlDocumentContext; import org.hibernate.boot.models.xml.spi.XmlDocumentContext;
import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.models.spi.AnnotationTarget;
import org.hibernate.models.spi.MutableAnnotationUsage; import org.hibernate.models.spi.MutableAnnotationUsage;
import org.hibernate.models.spi.MutableMemberDetails; import org.hibernate.models.spi.MutableMemberDetails;
import jakarta.persistence.AssociationOverride;
import jakarta.persistence.JoinTable; import jakarta.persistence.JoinTable;
/** /**
@ -35,15 +38,41 @@ public class TableProcessing {
JpaAnnotations.JOIN_TABLE, JpaAnnotations.JOIN_TABLE,
xmlDocumentContext.getModelBuildingContext() xmlDocumentContext.getModelBuildingContext()
); );
applyJoinTable( jaxbJoinTable, joinTableUsage, memberDetails, xmlDocumentContext );
return joinTableUsage;
}
public static MutableAnnotationUsage<JoinTable> createNestedJoinTable(
JaxbJoinTableImpl jaxbJoinTable,
AnnotationTarget annotationTarget,
XmlDocumentContext xmlDocumentContext) {
if ( jaxbJoinTable == null ) {
return null;
}
final MutableAnnotationUsage<JoinTable> joinTableAnn = XmlProcessingHelper.makeNestedAnnotation(
JoinTable.class,
annotationTarget,
xmlDocumentContext
);
applyJoinTable( jaxbJoinTable, joinTableAnn, annotationTarget, xmlDocumentContext );
return joinTableAnn;
}
private static void applyJoinTable(
JaxbJoinTableImpl jaxbJoinTable,
MutableAnnotationUsage<JoinTable> joinTableUsage,
AnnotationTarget annotationTarget,
XmlDocumentContext xmlDocumentContext) {
XmlAnnotationHelper.applyOptionalAttribute( joinTableUsage, "name", jaxbJoinTable.getName() ); XmlAnnotationHelper.applyOptionalAttribute( joinTableUsage, "name", jaxbJoinTable.getName() );
XmlAnnotationHelper.applyTableAttributes( jaxbJoinTable, memberDetails, joinTableUsage, JpaAnnotations.JOIN_TABLE, xmlDocumentContext ); XmlAnnotationHelper.applyTableAttributes( jaxbJoinTable, annotationTarget, joinTableUsage, JpaAnnotations.JOIN_TABLE, xmlDocumentContext );
final List<JaxbJoinColumnImpl> joinColumns = jaxbJoinTable.getJoinColumn(); final List<JaxbJoinColumnImpl> joinColumns = jaxbJoinTable.getJoinColumn();
if ( CollectionHelper.isNotEmpty( joinColumns ) ) { if ( CollectionHelper.isNotEmpty( joinColumns ) ) {
joinTableUsage.setAttributeValue( "joinColumns", JoinColumnProcessing.transformJoinColumnList( joinTableUsage.setAttributeValue( "joinColumns", JoinColumnProcessing.transformJoinColumnList(
joinColumns, joinColumns,
memberDetails, annotationTarget,
xmlDocumentContext xmlDocumentContext
) ); ) );
} }
@ -51,7 +80,7 @@ public class TableProcessing {
if ( CollectionHelper.isNotEmpty( inverseJoinColumns ) ) { if ( CollectionHelper.isNotEmpty( inverseJoinColumns ) ) {
joinTableUsage.setAttributeValue( "inverseJoinColumns", JoinColumnProcessing.transformJoinColumnList( joinTableUsage.setAttributeValue( "inverseJoinColumns", JoinColumnProcessing.transformJoinColumnList(
inverseJoinColumns, inverseJoinColumns,
memberDetails, annotationTarget,
xmlDocumentContext xmlDocumentContext
) ); ) );
} }
@ -59,16 +88,14 @@ public class TableProcessing {
if ( jaxbJoinTable.getForeignKey() != null ) { if ( jaxbJoinTable.getForeignKey() != null ) {
joinTableUsage.setAttributeValue( joinTableUsage.setAttributeValue(
"foreignKey", "foreignKey",
ForeignKeyProcessing.createNestedForeignKeyAnnotation( jaxbJoinTable.getForeignKey(), memberDetails, xmlDocumentContext ) ForeignKeyProcessing.createNestedForeignKeyAnnotation( jaxbJoinTable.getForeignKey(), annotationTarget, xmlDocumentContext )
); );
} }
if ( jaxbJoinTable.getInverseForeignKey() != null ) { if ( jaxbJoinTable.getInverseForeignKey() != null ) {
joinTableUsage.setAttributeValue( joinTableUsage.setAttributeValue(
"inverseForeignKey", "inverseForeignKey",
ForeignKeyProcessing.createNestedForeignKeyAnnotation( jaxbJoinTable.getInverseForeignKey(), memberDetails, xmlDocumentContext ) ForeignKeyProcessing.createNestedForeignKeyAnnotation( jaxbJoinTable.getInverseForeignKey(), annotationTarget, xmlDocumentContext )
); );
} }
return joinTableUsage;
} }
} }

View File

@ -13,11 +13,14 @@ import org.hibernate.CacheMode;
import org.hibernate.FlushMode; import org.hibernate.FlushMode;
import org.hibernate.LockOptions; import org.hibernate.LockOptions;
import org.checkerframework.checker.nullness.qual.Nullable;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public abstract class AbstractNamedQueryBuilder<T extends AbstractNamedQueryBuilder<T>> { public abstract class AbstractNamedQueryBuilder<R, T extends AbstractNamedQueryBuilder<R, T>> {
private final String name; private final String name;
private @Nullable Class<R> resultClass;
private Boolean cacheable; private Boolean cacheable;
private String cacheRegion; private String cacheRegion;
@ -45,6 +48,11 @@ public abstract class AbstractNamedQueryBuilder<T extends AbstractNamedQueryBuil
protected abstract T getThis(); protected abstract T getThis();
public T setResultClass(Class<R> resultClass) {
this.resultClass = resultClass;
return getThis();
}
public T setCacheable(Boolean cacheable) { public T setCacheable(Boolean cacheable) {
this.cacheable = cacheable; this.cacheable = cacheable;
return getThis(); return getThis();
@ -90,6 +98,10 @@ public abstract class AbstractNamedQueryBuilder<T extends AbstractNamedQueryBuil
return getThis(); return getThis();
} }
public Class<R> getResultClass() {
return resultClass;
}
public Boolean getCacheable() { public Boolean getCacheable() {
return cacheable; return cacheable;
} }

View File

@ -1,26 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.boot.query;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.procedure.internal.NamedCallableQueryMementoImpl;
import org.hibernate.procedure.spi.NamedCallableQueryMemento;
/**
* Named query mapping for callable queries
*
* @author Steve Ebersole
* @author Gavin King
*/
public interface NamedCallableQueryDefinition extends NamedQueryDefinition {
@Override
NamedCallableQueryMemento resolve(SessionFactoryImplementor factory);
interface ParameterMapping {
NamedCallableQueryMementoImpl.ParameterMementoImpl resolve(SessionFactoryImplementor factory);
}
}

View File

@ -23,13 +23,13 @@ import org.hibernate.query.sqm.spi.NamedSqmQueryMemento;
* @author Steve Ebersole * @author Steve Ebersole
* @author Gavin King * @author Gavin King
*/ */
public interface NamedHqlQueryDefinition extends NamedQueryDefinition { public interface NamedHqlQueryDefinition<E> extends NamedQueryDefinition<E> {
String getHqlString(); String getHqlString();
@Override @Override
NamedSqmQueryMemento resolve(SessionFactoryImplementor factory); NamedSqmQueryMemento<E> resolve(SessionFactoryImplementor factory);
class Builder extends AbstractNamedQueryBuilder<Builder> { class Builder<E> extends AbstractNamedQueryBuilder<E, Builder<E>> {
private String hqlString; private String hqlString;
private Integer firstResult; private Integer firstResult;
@ -42,7 +42,7 @@ public interface NamedHqlQueryDefinition extends NamedQueryDefinition {
} }
@Override @Override
protected Builder getThis() { protected Builder<E> getThis() {
return this; return this;
} }
@ -50,24 +50,25 @@ public interface NamedHqlQueryDefinition extends NamedQueryDefinition {
return hqlString; return hqlString;
} }
public Builder setHqlString(String hqlString) { public Builder<E> setHqlString(String hqlString) {
this.hqlString = hqlString; this.hqlString = hqlString;
return this; return this;
} }
public Builder setFirstResult(Integer firstResult) { public Builder<E> setFirstResult(Integer firstResult) {
this.firstResult = firstResult; this.firstResult = firstResult;
return getThis(); return getThis();
} }
public Builder setMaxResults(Integer maxResults) { public Builder<E> setMaxResults(Integer maxResults) {
this.maxResults = maxResults; this.maxResults = maxResults;
return getThis(); return getThis();
} }
public NamedHqlQueryDefinitionImpl build() { public NamedHqlQueryDefinitionImpl<E> build() {
return new NamedHqlQueryDefinitionImpl( return new NamedHqlQueryDefinitionImpl<>(
getName(), getName(),
getResultClass(),
hqlString, hqlString,
firstResult, firstResult,
maxResults, maxResults,

View File

@ -6,13 +6,13 @@
*/ */
package org.hibernate.boot.query; package org.hibernate.boot.query;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.hibernate.boot.internal.NamedNativeQueryDefinitionImpl; import org.hibernate.boot.internal.NamedNativeQueryDefinitionImpl;
import org.hibernate.boot.spi.AbstractNamedQueryDefinition;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.query.sql.spi.NamedNativeQueryMemento; import org.hibernate.query.sql.spi.NamedNativeQueryMemento;
@ -26,13 +26,110 @@ import org.hibernate.query.sql.spi.NamedNativeQueryMemento;
* @author Steve Ebersole * @author Steve Ebersole
* @author Gavin King * @author Gavin King
*/ */
public interface NamedNativeQueryDefinition extends NamedQueryDefinition { public interface NamedNativeQueryDefinition<E> extends NamedQueryDefinition<E> {
String getSqlQueryString(); String getSqlQueryString();
String getResultSetMappingName(); String getResultSetMappingName();
String getResultSetMappingClassName();
@Override @Override
NamedNativeQueryMemento resolve(SessionFactoryImplementor factory); NamedNativeQueryMemento<E> resolve(SessionFactoryImplementor factory);
class Builder<E> extends AbstractNamedQueryBuilder<E, Builder<E>> {
private String sqlString;
private String resultSetMappingName;
private Set<String> querySpaces;
private Map<String, String> parameterTypes;
private Integer firstResult;
private Integer maxResults;
public Builder(String name) {
super( name );
}
public Builder<E> setSqlString(String sqlString) {
this.sqlString = sqlString;
return getThis();
}
public Builder<E> setFirstResult(Integer firstResult) {
this.firstResult = firstResult;
return getThis();
}
public Builder<E> setMaxResults(Integer maxResults) {
this.maxResults = maxResults;
return getThis();
}
public NamedNativeQueryDefinition<E> build() {
return new NamedNativeQueryDefinitionImpl<>(
getName(),
getResultClass(),
sqlString,
resultSetMappingName,
getQuerySpaces(),
getCacheable(),
getCacheRegion(),
getCacheMode(),
getFlushMode(),
getReadOnly(),
getTimeout(),
getFetchSize(),
getComment(),
firstResult,
maxResults,
getHints()
);
}
@Override
protected Builder<E> getThis() {
return this;
}
public String getSqlString() {
return sqlString;
}
public Set<String> getQuerySpaces() {
return querySpaces;
}
public Map<String, String> getParameterTypes() {
return parameterTypes == null ? Collections.emptyMap() : parameterTypes;
}
public String getResultSetMappingName() {
return resultSetMappingName;
}
public Builder<E> addSynchronizedQuerySpace(String space) {
if ( this.querySpaces == null ) {
this.querySpaces = new HashSet<>();
}
this.querySpaces.add( space );
return getThis();
}
public Builder<E> setQuerySpaces(Set<String> spaces) {
this.querySpaces = spaces;
return this;
}
public Builder<E> setResultSetMappingName(String resultSetMappingName) {
this.resultSetMappingName = resultSetMappingName;
return this;
}
public void addParameterTypeHint(String name, String type) {
if ( parameterTypes == null ) {
parameterTypes = new HashMap<>();
}
parameterTypes.put( name, type );
}
}
} }

View File

@ -1,127 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.boot.query;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.hibernate.boot.internal.NamedNativeQueryDefinitionImpl;
/**
* @author Steve Ebersole
*/
public class NamedNativeQueryDefinitionBuilder extends AbstractNamedQueryBuilder<NamedNativeQueryDefinitionBuilder> {
private String sqlString;
private String resultSetMappingName;
private String resultSetMappingClassName;
private Set<String> querySpaces;
private Map<String, String> parameterTypes;
private Integer firstResult;
private Integer maxResults;
public NamedNativeQueryDefinitionBuilder(String name) {
super( name );
}
public NamedNativeQueryDefinitionBuilder setSqlString(String sqlString) {
this.sqlString = sqlString;
return getThis();
}
public NamedNativeQueryDefinitionBuilder setFirstResult(Integer firstResult) {
this.firstResult = firstResult;
return getThis();
}
public NamedNativeQueryDefinitionBuilder setMaxResults(Integer maxResults) {
this.maxResults = maxResults;
return getThis();
}
public NamedNativeQueryDefinition build() {
return new NamedNativeQueryDefinitionImpl(
getName(),
sqlString,
resultSetMappingName,
resultSetMappingClassName,
getQuerySpaces(),
getCacheable(),
getCacheRegion(),
getCacheMode(),
getFlushMode(),
getReadOnly(),
getTimeout(),
getFetchSize(),
getComment(),
firstResult,
maxResults,
getHints()
);
}
@Override
protected NamedNativeQueryDefinitionBuilder getThis() {
return this;
}
public String getSqlString() {
return sqlString;
}
public Set<String> getQuerySpaces() {
return querySpaces;
}
public Map<String, String> getParameterTypes() {
return parameterTypes == null ? Collections.emptyMap() : parameterTypes;
}
public String getResultSetMappingName() {
return resultSetMappingName;
}
public String getResultSetMappingClassName() {
return resultSetMappingClassName;
}
public NamedNativeQueryDefinitionBuilder addSynchronizedQuerySpace(String space) {
if ( this.querySpaces == null ) {
this.querySpaces = new HashSet<>();
}
this.querySpaces.add( space );
return getThis();
}
public NamedNativeQueryDefinitionBuilder setQuerySpaces(Set<String> spaces) {
this.querySpaces = spaces;
return this;
}
public NamedNativeQueryDefinitionBuilder setResultSetMappingName(String resultSetMappingName) {
this.resultSetMappingName = resultSetMappingName;
return this;
}
public NamedNativeQueryDefinitionBuilder setResultSetMappingClassName(String resultSetMappingClassName) {
this.resultSetMappingClassName = resultSetMappingClassName;
return this;
}
public void addParameterTypeHint(String name, String type) {
if ( parameterTypes == null ) {
parameterTypes = new HashMap<>();
}
parameterTypes.put( name, type );
}
}

View File

@ -17,12 +17,17 @@ import org.hibernate.procedure.spi.NamedCallableQueryMemento;
* *
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public interface NamedProcedureCallDefinition extends NamedQueryDefinition { public interface NamedProcedureCallDefinition extends NamedQueryDefinition<Object> {
/** /**
* The name of the underlying database procedure or function name * The name of the underlying database procedure or function name
*/ */
String getProcedureName(); String getProcedureName();
@Override
default Class<Object> getResultType() {
return Object.class;
}
@Override @Override
NamedCallableQueryMemento resolve(SessionFactoryImplementor factory); NamedCallableQueryMemento resolve(SessionFactoryImplementor factory);
} }

View File

@ -9,6 +9,8 @@ package org.hibernate.boot.query;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.query.named.NamedQueryMemento; import org.hibernate.query.named.NamedQueryMemento;
import org.checkerframework.checker.nullness.qual.Nullable;
/** /**
* Common attributes shared across the mapping of named HQL, native * Common attributes shared across the mapping of named HQL, native
* and "callable" queries defined in annotations, orm.xml and hbm.xml * and "callable" queries defined in annotations, orm.xml and hbm.xml
@ -16,14 +18,20 @@ import org.hibernate.query.named.NamedQueryMemento;
* @author Steve Ebersole * @author Steve Ebersole
* @author Gavin King * @author Gavin King
*/ */
public interface NamedQueryDefinition { public interface NamedQueryDefinition<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();
/**
* The expected result type of the query, or {@code null}.
*/
@Nullable
Class<E> getResultType();
/** /**
* Resolve the mapping definition into its run-time memento form * Resolve the mapping definition into its run-time memento form
*/ */
NamedQueryMemento resolve(SessionFactoryImplementor factory); NamedQueryMemento<E> resolve(SessionFactoryImplementor factory);
} }

View File

@ -117,22 +117,22 @@ public abstract class AbstractDelegatingMetadata implements MetadataImplementor
} }
@Override @Override
public NamedHqlQueryDefinition getNamedHqlQueryMapping(String name) { public NamedHqlQueryDefinition<?> getNamedHqlQueryMapping(String name) {
return delegate.getNamedHqlQueryMapping( name ); return delegate.getNamedHqlQueryMapping( name );
} }
@Override @Override
public void visitNamedHqlQueryDefinitions(Consumer<NamedHqlQueryDefinition> definitionConsumer) { public void visitNamedHqlQueryDefinitions(Consumer<NamedHqlQueryDefinition<?>> definitionConsumer) {
delegate.visitNamedHqlQueryDefinitions( definitionConsumer ); delegate.visitNamedHqlQueryDefinitions( definitionConsumer );
} }
@Override @Override
public NamedNativeQueryDefinition getNamedNativeQueryMapping(String name) { public NamedNativeQueryDefinition<?> getNamedNativeQueryMapping(String name) {
return delegate.getNamedNativeQueryMapping( name ); return delegate.getNamedNativeQueryMapping( name );
} }
@Override @Override
public void visitNamedNativeQueryDefinitions(Consumer<NamedNativeQueryDefinition> definitionConsumer) { public void visitNamedNativeQueryDefinitions(Consumer<NamedNativeQueryDefinition<?>> definitionConsumer) {
delegate.visitNamedNativeQueryDefinitions( definitionConsumer ); delegate.visitNamedNativeQueryDefinitions( definitionConsumer );
} }

View File

@ -14,11 +14,14 @@ import org.hibernate.FlushMode;
import org.hibernate.LockOptions; import org.hibernate.LockOptions;
import org.hibernate.boot.query.NamedQueryDefinition; import org.hibernate.boot.query.NamedQueryDefinition;
import org.checkerframework.checker.nullness.qual.Nullable;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public abstract class AbstractNamedQueryDefinition implements NamedQueryDefinition { public abstract class AbstractNamedQueryDefinition<R> implements NamedQueryDefinition<R> {
private final String name; private final String name;
private final @Nullable Class<R> resultType;
private final Boolean cacheable; private final Boolean cacheable;
private final String cacheRegion; private final String cacheRegion;
@ -38,6 +41,7 @@ public abstract class AbstractNamedQueryDefinition implements NamedQueryDefiniti
public AbstractNamedQueryDefinition( public AbstractNamedQueryDefinition(
String name, String name,
@Nullable Class<R> resultType,
Boolean cacheable, Boolean cacheable,
String cacheRegion, String cacheRegion,
CacheMode cacheMode, CacheMode cacheMode,
@ -49,6 +53,7 @@ public abstract class AbstractNamedQueryDefinition implements NamedQueryDefiniti
String comment, String comment,
Map<String,Object> hints) { Map<String,Object> hints) {
this.name = name; this.name = name;
this.resultType = resultType;
this.cacheable = cacheable; this.cacheable = cacheable;
this.cacheRegion = cacheRegion; this.cacheRegion = cacheRegion;
this.cacheMode = cacheMode; this.cacheMode = cacheMode;
@ -66,6 +71,11 @@ public abstract class AbstractNamedQueryDefinition implements NamedQueryDefiniti
return name; return name;
} }
@Override
public @Nullable Class<R> getResultType() {
return resultType;
}
public Boolean getCacheable() { public Boolean getCacheable() {
return cacheable; return cacheable;
} }

View File

@ -180,12 +180,12 @@ public interface InFlightMetadataCollector extends MetadataImplementor {
* *
* @throws DuplicateMappingException If a query already exists with that name. * @throws DuplicateMappingException If a query already exists with that name.
*/ */
void addNamedQuery(NamedHqlQueryDefinition query) throws DuplicateMappingException; void addNamedQuery(NamedHqlQueryDefinition<?> query) throws DuplicateMappingException;
/** /**
* Adds metadata for a named SQL query to this collector. * Adds metadata for a named SQL query to this collector.
*/ */
void addNamedNativeQuery(NamedNativeQueryDefinition query) throws DuplicateMappingException; void addNamedNativeQuery(NamedNativeQueryDefinition<?> query) throws DuplicateMappingException;
/** /**
* Adds the metadata for a named SQL result set mapping to this collector. * Adds the metadata for a named SQL result set mapping to this collector.
@ -318,9 +318,9 @@ public interface InFlightMetadataCollector extends MetadataImplementor {
void addDefaultIdentifierGenerator(IdentifierGeneratorDefinition generatorDefinition); void addDefaultIdentifierGenerator(IdentifierGeneratorDefinition generatorDefinition);
void addDefaultQuery(NamedHqlQueryDefinition queryDefinition); void addDefaultQuery(NamedHqlQueryDefinition<?> queryDefinition);
void addDefaultNamedNativeQuery(NamedNativeQueryDefinition query); void addDefaultNamedNativeQuery(NamedNativeQueryDefinition<?> query);
void addDefaultResultSetMapping(NamedResultSetMappingDescriptor definition); void addDefaultResultSetMapping(NamedResultSetMappingDescriptor definition);

View File

@ -137,8 +137,8 @@ public class Configuration {
private List<UserTypeRegistration> userTypeRegistrations; private List<UserTypeRegistration> userTypeRegistrations;
private final List<TypeContributor> typeContributorRegistrations = new ArrayList<>(); private final List<TypeContributor> typeContributorRegistrations = new ArrayList<>();
private final List<FunctionContributor> functionContributorRegistrations = new ArrayList<>(); private final List<FunctionContributor> functionContributorRegistrations = new ArrayList<>();
private final Map<String, NamedHqlQueryDefinition> namedQueries = new HashMap<>(); private final Map<String, NamedHqlQueryDefinition<?>> namedQueries = new HashMap<>();
private final Map<String, NamedNativeQueryDefinition> namedSqlQueries = new HashMap<>(); private final Map<String, NamedNativeQueryDefinition<?>> namedSqlQueries = new HashMap<>();
private final Map<String, NamedProcedureCallDefinition> namedProcedureCallMap = new HashMap<>(); private final Map<String, NamedProcedureCallDefinition> namedProcedureCallMap = new HashMap<>();
private final Map<String, NamedResultSetMappingDescriptor> sqlResultSetMappings = new HashMap<>(); private final Map<String, NamedResultSetMappingDescriptor> sqlResultSetMappings = new HashMap<>();
private final Map<String, NamedEntityGraphDefinition> namedEntityGraphMap = new HashMap<>(); private final Map<String, NamedEntityGraphDefinition> namedEntityGraphMap = new HashMap<>();
@ -1155,7 +1155,7 @@ public class Configuration {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// todo : decide about these // todo : decide about these
public Map<String, NamedNativeQueryDefinition> getNamedSQLQueries() { public Map<String, NamedNativeQueryDefinition<?>> getNamedSQLQueries() {
return namedSqlQueries; return namedSqlQueries;
} }
@ -1168,7 +1168,7 @@ public class Configuration {
} }
public Map<String, NamedHqlQueryDefinition> getNamedQueries() { public Map<String, NamedHqlQueryDefinition<?>> getNamedQueries() {
return namedQueries; return namedQueries;
} }

View File

@ -70,6 +70,7 @@ import jakarta.persistence.FlushModeType;
import jakarta.persistence.LockModeType; import jakarta.persistence.LockModeType;
import jakarta.persistence.LockOption; import jakarta.persistence.LockOption;
import jakarta.persistence.RefreshOption; import jakarta.persistence.RefreshOption;
import jakarta.persistence.TypedQueryReference;
import jakarta.persistence.criteria.CriteriaDelete; import jakarta.persistence.criteria.CriteriaDelete;
import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.CriteriaSelect; import jakarta.persistence.criteria.CriteriaSelect;
@ -561,6 +562,11 @@ public class SessionDelegatorBaseImpl implements SessionImplementor {
return queryDelegate().createQuery( deleteQuery ); return queryDelegate().createQuery( deleteQuery );
} }
@Override
public <T> QueryImplementor<T> createQuery(TypedQueryReference<T> typedQueryReference) {
return queryDelegate().createQuery( typedQueryReference );
}
@Override @SuppressWarnings("rawtypes") @Override @SuppressWarnings("rawtypes")
public QueryImplementor getNamedQuery(String name) { public QueryImplementor getNamedQuery(String name) {
return queryDelegate().getNamedQuery( name ); return queryDelegate().getNamedQuery( name );

View File

@ -21,6 +21,7 @@ import jakarta.persistence.PersistenceUnitTransactionType;
import jakarta.persistence.PersistenceUnitUtil; import jakarta.persistence.PersistenceUnitUtil;
import jakarta.persistence.Query; import jakarta.persistence.Query;
import jakarta.persistence.SynchronizationType; import jakarta.persistence.SynchronizationType;
import jakarta.persistence.TypedQueryReference;
import org.hibernate.CustomEntityDirtinessStrategy; import org.hibernate.CustomEntityDirtinessStrategy;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
@ -234,6 +235,16 @@ public class SessionFactoryDelegatingImpl implements SessionFactoryImplementor,
return delegate.findEntityGraphByName( name ); return delegate.findEntityGraphByName( name );
} }
@Override
public <R> Map<String, TypedQueryReference<R>> getNamedQueries(Class<R> resultType) {
return delegate.getNamedQueries( resultType );
}
@Override
public <E> Map<String, EntityGraph<? extends E>> getNamedEntityGraphs(Class<E> entityType) {
return delegate.getNamedEntityGraphs( entityType );
}
@Override @Override
public String bestGuessEntityName(Object object) { public String bestGuessEntityName(Object object) {
return delegate.bestGuessEntityName( object ); return delegate.bestGuessEntityName( object );

View File

@ -54,6 +54,7 @@ import jakarta.persistence.LockModeType;
import jakarta.persistence.LockOption; import jakarta.persistence.LockOption;
import jakarta.persistence.RefreshOption; import jakarta.persistence.RefreshOption;
import jakarta.persistence.TypedQuery; import jakarta.persistence.TypedQuery;
import jakarta.persistence.TypedQueryReference;
import jakarta.persistence.criteria.CriteriaDelete; import jakarta.persistence.criteria.CriteriaDelete;
import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.CriteriaSelect; import jakarta.persistence.criteria.CriteriaSelect;
@ -569,6 +570,11 @@ public class SessionLazyDelegator implements Session {
return this.lazySession.get().createQuery( queryString, resultClass ); return this.lazySession.get().createQuery( queryString, resultClass );
} }
@Override
public <R> Query<R> createQuery(TypedQueryReference<R> typedQueryReference) {
return this.lazySession.get().createQuery( typedQueryReference );
}
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
@Override @Override
@Deprecated @Deprecated

View File

@ -8,6 +8,7 @@ package org.hibernate.engine.spi;
import jakarta.persistence.EntityGraph; import jakarta.persistence.EntityGraph;
import jakarta.persistence.FlushModeType; import jakarta.persistence.FlushModeType;
import jakarta.persistence.TypedQueryReference;
import jakarta.persistence.criteria.CriteriaDelete; import jakarta.persistence.criteria.CriteriaDelete;
import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.CriteriaUpdate; import jakarta.persistence.criteria.CriteriaUpdate;
@ -164,6 +165,11 @@ public class SharedSessionDelegatorBaseImpl implements SharedSessionContractImpl
return queryDelegate().createQuery( queryString, resultType ); return queryDelegate().createQuery( queryString, resultType );
} }
@Override
public <R> QueryImplementor<R> createQuery(TypedQueryReference<R> typedQueryReference) {
return queryDelegate().createQuery( typedQueryReference );
}
@Override @SuppressWarnings("rawtypes") @Override @SuppressWarnings("rawtypes")
public QueryImplementor createNamedQuery(String name) { public QueryImplementor createNamedQuery(String name) {
return queryDelegate().createNamedQuery( name ); return queryDelegate().createNamedQuery( name );

View File

@ -7,6 +7,7 @@
package org.hibernate.engine.transaction.internal; package org.hibernate.engine.transaction.internal;
import jakarta.transaction.Synchronization; import jakarta.transaction.Synchronization;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.TransactionException; import org.hibernate.TransactionException;
@ -187,8 +188,17 @@ public class TransactionImpl implements TransactionImplementor {
} }
@Override @Override
public int getTimeout() { public void setTimeout(@Nullable Integer seconds) {
return this.transactionCoordinator.getTimeOut(); this.transactionCoordinator.setTimeOut( seconds == null ? -1 : seconds );
}
@Override
public @Nullable Integer getTimeout() {
final int timeOut = this.transactionCoordinator.getTimeOut();
if ( timeOut == -1 ) {
return null;
}
return timeOut;
} }
@Override @Override

View File

@ -111,6 +111,7 @@ import jakarta.persistence.FlushModeType;
import jakarta.persistence.NamedNativeQuery; import jakarta.persistence.NamedNativeQuery;
import jakarta.persistence.TransactionRequiredException; import jakarta.persistence.TransactionRequiredException;
import jakarta.persistence.Tuple; import jakarta.persistence.Tuple;
import jakarta.persistence.TypedQueryReference;
import jakarta.persistence.criteria.CriteriaDelete; import jakarta.persistence.criteria.CriteriaDelete;
import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.CriteriaUpdate; import jakarta.persistence.criteria.CriteriaUpdate;
@ -887,8 +888,20 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
} }
} }
@Override
public <R> QueryImplementor<R> createQuery(TypedQueryReference<R> typedQueryReference) {
//noinspection unchecked
final QueryImplementor<R> query = (QueryImplementor<R>) createNamedQuery(
typedQueryReference.getName(),
typedQueryReference.getResultType()
);
for ( Map.Entry<String, Object> entry : typedQueryReference.getHints().entrySet() ) {
query.setHint( entry.getKey(), entry.getValue() );
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ return query;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// dynamic native (SQL) query handling // dynamic native (SQL) query handling
@Override @SuppressWarnings("rawtypes") @Override @SuppressWarnings("rawtypes")

View File

@ -132,6 +132,7 @@ import jakarta.persistence.PersistenceUnitTransactionType;
import jakarta.persistence.PersistenceUnitUtil; import jakarta.persistence.PersistenceUnitUtil;
import jakarta.persistence.Query; import jakarta.persistence.Query;
import jakarta.persistence.SynchronizationType; import jakarta.persistence.SynchronizationType;
import jakarta.persistence.TypedQueryReference;
import static jakarta.persistence.SynchronizationType.SYNCHRONIZED; import static jakarta.persistence.SynchronizationType.SYNCHRONIZED;
import static java.util.Collections.emptySet; import static java.util.Collections.emptySet;
@ -1081,6 +1082,16 @@ public class SessionFactoryImpl extends QueryParameterBindingTypeResolverImpl im
getMappingMetamodel().addNamedEntityGraph( graphName, (RootGraphImplementor<T>) entityGraph ); getMappingMetamodel().addNamedEntityGraph( graphName, (RootGraphImplementor<T>) entityGraph );
} }
@Override
public <R> Map<String, TypedQueryReference<R>> getNamedQueries(Class<R> resultType) {
return queryEngine.getNamedObjectRepository().getNamedQueries( resultType );
}
@Override
public <E> Map<String, EntityGraph<? extends E>> getNamedEntityGraphs(Class<E> entityType) {
return getJpaMetamodel().getNamedEntityGraphs( entityType );
}
@Override @Override
public void runInTransaction(Consumer<EntityManager> work) { public void runInTransaction(Consumer<EntityManager> work) {
//noinspection unchecked,rawtypes //noinspection unchecked,rawtypes

View File

@ -69,14 +69,12 @@ public class PersistenceUnitUtilImpl implements PersistenceUnitUtil, Serializabl
@Override @Override
public void load(Object entity, String attributeName) { public void load(Object entity, String attributeName) {
// todo (jpa 3.2) : implement this Hibernate.initializeProperty( entity, attributeName );
throw new UnsupportedOperationException( "Not yet implemented" );
} }
@Override @Override
public <E> void load(E entity, Attribute<? super E, ?> attribute) { public <E> void load(E entity, Attribute<? super E, ?> attribute) {
// todo (jpa 3.2) : implement this load( entity, attribute.getName() );
throw new UnsupportedOperationException( "Not yet implemented" );
} }
@Override @Override
@ -86,14 +84,12 @@ public class PersistenceUnitUtilImpl implements PersistenceUnitUtil, Serializabl
@Override @Override
public boolean isInstance(Object entity, Class<?> entityClass) { public boolean isInstance(Object entity, Class<?> entityClass) {
// todo (jpa 3.2) : implement this return entityClass.isAssignableFrom( Hibernate.getClassLazy( entity ) );
throw new UnsupportedOperationException( "Not yet implemented" );
} }
@Override @Override
public <T> Class<? extends T> getClass(T entity) { public <T> Class<? extends T> getClass(T entity) {
// todo (jpa 3.2) : implement this return Hibernate.getClassLazy( entity );
throw new UnsupportedOperationException( "Not yet implemented" );
} }
@Override @Override
@ -129,8 +125,26 @@ public class PersistenceUnitUtilImpl implements PersistenceUnitUtil, Serializabl
@Override @Override
public Object getVersion(Object entity) { public Object getVersion(Object entity) {
// todo (jpa 3.2) : implement this if ( entity == null ) {
throw new UnsupportedOperationException( "Not yet implemented" ); throw new IllegalArgumentException( "Passed entity cannot be null" );
}
final LazyInitializer lazyInitializer = extractLazyInitializer( entity );
if ( lazyInitializer != null ) {
return getVersionFromPersister( lazyInitializer.getImplementation() );
}
else if ( isManagedEntity( entity ) ) {
final EntityEntry entityEntry = asManagedEntity( entity ).$$_hibernate_getEntityEntry();
if ( entityEntry != null ) {
return entityEntry.getVersion();
}
else {
return getVersionFromPersister( entity );
}
}
else {
return getVersionFromPersister( entity );
}
} }
private Object getIdentifierFromPersister(Object entity) { private Object getIdentifierFromPersister(Object entity) {
@ -150,4 +164,21 @@ public class PersistenceUnitUtilImpl implements PersistenceUnitUtil, Serializabl
return persister.getIdentifier( entity, null ); return persister.getIdentifier( entity, null );
} }
private Object getVersionFromPersister(Object entity) {
final Class<?> entityClass = Hibernate.getClass( entity );
final EntityPersister persister;
try {
persister = sessionFactory.getRuntimeMetamodels()
.getMappingMetamodel()
.getEntityDescriptor( entityClass );
if ( persister == null ) {
throw new IllegalArgumentException( entityClass.getName() + " is not an entity" );
}
}
catch (MappingException ex) {
throw new IllegalArgumentException( entityClass.getName() + " is not an entity", ex );
}
return persister.getVersion( entity );
}
} }

View File

@ -26,9 +26,9 @@ import java.util.List;
*/ */
public class CollectionLoaderNamedQuery implements CollectionLoader { public class CollectionLoaderNamedQuery implements CollectionLoader {
private final CollectionPersister persister; private final CollectionPersister persister;
private final NamedQueryMemento namedQueryMemento; private final NamedQueryMemento<?> namedQueryMemento;
public CollectionLoaderNamedQuery(CollectionPersister persister, NamedQueryMemento namedQueryMemento) { public CollectionLoaderNamedQuery(CollectionPersister persister, NamedQueryMemento<?> namedQueryMemento) {
this.persister = persister; this.persister = persister;
this.namedQueryMemento = namedQueryMemento; this.namedQueryMemento = namedQueryMemento;
} }

View File

@ -25,11 +25,11 @@ import jakarta.persistence.Parameter;
*/ */
public class SingleIdEntityLoaderProvidedQueryImpl<T> implements SingleIdEntityLoader<T> { public class SingleIdEntityLoaderProvidedQueryImpl<T> implements SingleIdEntityLoader<T> {
private final EntityMappingType entityDescriptor; private final EntityMappingType entityDescriptor;
private final NamedQueryMemento namedQueryMemento; private final NamedQueryMemento<?> namedQueryMemento;
public SingleIdEntityLoaderProvidedQueryImpl( public SingleIdEntityLoaderProvidedQueryImpl(
EntityMappingType entityDescriptor, EntityMappingType entityDescriptor,
NamedQueryMemento namedQueryMemento) { NamedQueryMemento<?> namedQueryMemento) {
this.entityDescriptor = entityDescriptor; this.entityDescriptor = entityDescriptor;
this.namedQueryMemento = namedQueryMemento; this.namedQueryMemento = namedQueryMemento;
} }

View File

@ -7,7 +7,10 @@
package org.hibernate.metamodel.model.domain; package org.hibernate.metamodel.model.domain;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import jakarta.persistence.EntityGraph;
import jakarta.persistence.metamodel.EmbeddableType; import jakarta.persistence.metamodel.EmbeddableType;
import jakarta.persistence.metamodel.EntityType; import jakarta.persistence.metamodel.EntityType;
import jakarta.persistence.metamodel.ManagedType; import jakarta.persistence.metamodel.ManagedType;
@ -131,5 +134,7 @@ public interface JpaMetamodel extends Metamodel {
<T> List<RootGraphImplementor<? super T>> findEntityGraphsByJavaType(Class<T> entityClass); <T> List<RootGraphImplementor<? super T>> findEntityGraphsByJavaType(Class<T> entityClass);
<T> Map<String, EntityGraph<? extends T>> getNamedEntityGraphs(Class<T> entityType);
JpaCompliance getJpaCompliance(); JpaCompliance getJpaCompliance();
} }

View File

@ -370,6 +370,24 @@ public class JpaMetamodelImpl implements JpaMetamodelImplementor, Serializable {
} }
} }
@Override
public <T> Map<String, EntityGraph<? extends T>> getNamedEntityGraphs(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 Map<String, EntityGraph<? extends T>> results = new HashMap<>();
for ( RootGraphImplementor<?> entityGraph : entityGraphMap.values() ) {
if ( entityGraph.appliesTo( entityType ) ) {
//noinspection unchecked
results.put( entityGraph.getName(), (EntityGraph<? extends T>) entityGraph );
}
}
return results;
}
}
@Override @Override
public String qualifyImportableName(String queryName) { public String qualifyImportableName(String queryName) {
final ImportInfo<?> importInfo = resolveImport( queryName ); final ImportInfo<?> importInfo = resolveImport( queryName );

View File

@ -78,6 +78,7 @@ 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.EntityGraph;
import jakarta.persistence.metamodel.EmbeddableType; import jakarta.persistence.metamodel.EmbeddableType;
import jakarta.persistence.metamodel.EntityType; import jakarta.persistence.metamodel.EntityType;
import jakarta.persistence.metamodel.ManagedType; import jakarta.persistence.metamodel.ManagedType;
@ -688,6 +689,11 @@ public class MappingMetamodelImpl extends QueryParameterBindingTypeResolverImpl
return jpaMetamodel.findEntityGraphByName( name ); return jpaMetamodel.findEntityGraphByName( name );
} }
@Override
public <T> Map<String, EntityGraph<? extends T>> getNamedEntityGraphs(Class<T> entityType) {
return jpaMetamodel.getNamedEntityGraphs( entityType );
}
@Override @Override
public <T> List<RootGraphImplementor<? super T>> findEntityGraphsByJavaType(Class<T> entityClass) { public <T> List<RootGraphImplementor<? super T>> findEntityGraphsByJavaType(Class<T> entityClass) {
return jpaMetamodel.findEntityGraphsByJavaType( entityClass ); return jpaMetamodel.findEntityGraphsByJavaType( entityClass );

View File

@ -700,8 +700,8 @@ public abstract class AbstractCollectionPersister
logStaticSQL(); logStaticSQL();
} }
private NamedQueryMemento getNamedQueryMemento(MetadataImplementor bootModel) { private NamedQueryMemento<?> getNamedQueryMemento(MetadataImplementor bootModel) {
final NamedQueryMemento memento = final NamedQueryMemento<?> memento =
factory.getQueryEngine().getNamedObjectRepository() factory.getQueryEngine().getNamedObjectRepository()
.resolve( factory, bootModel, queryLoaderName ); .resolve( factory, bootModel, queryLoaderName );
if ( memento == null ) { if ( memento == null ) {
@ -847,7 +847,7 @@ public abstract class AbstractCollectionPersister
/** /**
* For Hibernate Reactive * For Hibernate Reactive
*/ */
protected CollectionLoader createNamedQueryCollectionLoader(CollectionPersister persister, NamedQueryMemento namedQueryMemento) { protected CollectionLoader createNamedQueryCollectionLoader(CollectionPersister persister, NamedQueryMemento<?> namedQueryMemento) {
return new CollectionLoaderNamedQuery(persister, namedQueryMemento); return new CollectionLoaderNamedQuery(persister, namedQueryMemento);
} }

View File

@ -861,8 +861,8 @@ public abstract class AbstractEntityPersister
} }
} }
private NamedQueryMemento getNamedQueryMemento(MetadataImplementor bootModel) { private NamedQueryMemento<?> getNamedQueryMemento(MetadataImplementor bootModel) {
final NamedQueryMemento memento = final NamedQueryMemento<?> memento =
factory.getQueryEngine().getNamedObjectRepository() factory.getQueryEngine().getNamedObjectRepository()
.resolve( factory, bootModel, queryLoaderName ); .resolve( factory, bootModel, queryLoaderName );
if ( memento == null ) { if ( memento == null ) {
@ -878,7 +878,7 @@ public abstract class AbstractEntityPersister
protected SingleIdEntityLoader<?> buildSingleIdEntityLoader() { protected SingleIdEntityLoader<?> buildSingleIdEntityLoader() {
if ( hasNamedQueryLoader() ) { if ( hasNamedQueryLoader() ) {
// We must resolve the named query on-demand through the boot model because it isn't initialized yet // We must resolve the named query on-demand through the boot model because it isn't initialized yet
final NamedQueryMemento memento = getNamedQueryMemento( null ); final NamedQueryMemento<?> memento = getNamedQueryMemento( null );
return new SingleIdEntityLoaderProvidedQueryImpl<>( this, memento ); return new SingleIdEntityLoaderProvidedQueryImpl<>( this, memento );
} }
return buildSingleIdEntityLoader( new LoadQueryInfluencers( factory ) ); return buildSingleIdEntityLoader( new LoadQueryInfluencers( factory ) );

View File

@ -30,7 +30,7 @@ import org.hibernate.query.spi.QueryImplementor;
* *
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class NamedCallableQueryMementoImpl extends AbstractNamedQueryMemento implements NamedCallableQueryMemento { public class NamedCallableQueryMementoImpl extends AbstractNamedQueryMemento<Object> implements NamedCallableQueryMemento {
private final String callableName; private final String callableName;
private final ParameterStrategy parameterStrategy; private final ParameterStrategy parameterStrategy;
@ -64,6 +64,7 @@ public class NamedCallableQueryMementoImpl extends AbstractNamedQueryMemento imp
Map<String, Object> hints) { Map<String, Object> hints) {
super( super(
name, name,
Object.class,
cacheable, cacheable,
cacheRegion, cacheRegion,
cacheMode, cacheMode,
@ -132,7 +133,7 @@ public class NamedCallableQueryMementoImpl extends AbstractNamedQueryMemento imp
} }
@Override @Override
public <T> QueryImplementor<T> toQuery(SharedSessionContractImplementor session) { public QueryImplementor<Object> toQuery(SharedSessionContractImplementor session) {
return new ProcedureCallImpl<>( session, this ); return new ProcedureCallImpl<>( session, this );
} }
@ -142,7 +143,7 @@ public class NamedCallableQueryMementoImpl extends AbstractNamedQueryMemento imp
} }
@Override @Override
public NamedQueryMemento makeCopy(String name) { public NamedQueryMemento<Object> makeCopy(String name) {
return new NamedCallableQueryMementoImpl( return new NamedCallableQueryMementoImpl(
name, name,
callableName, callableName,

View File

@ -22,7 +22,7 @@ import org.hibernate.query.named.NamedQueryMemento;
* @author Steve Ebersole * @author Steve Ebersole
*/ */
@Incubating @Incubating
public interface NamedCallableQueryMemento extends NamedQueryMemento { public interface NamedCallableQueryMemento extends NamedQueryMemento<Object> {
/** /**
* Informational access to the name of the database function or procedure * Informational access to the name of the database function or procedure
*/ */
@ -90,4 +90,9 @@ public interface NamedCallableQueryMemento extends NamedQueryMemento {
interface ParameterMemento extends NamedQueryMemento.ParameterMemento { interface ParameterMemento extends NamedQueryMemento.ParameterMemento {
ProcedureParameterImplementor<?> resolve(SharedSessionContractImplementor session); ProcedureParameterImplementor<?> resolve(SharedSessionContractImplementor session);
} }
@Override
default Class<?> getResultType() {
return Object.class;
}
} }

View File

@ -9,6 +9,7 @@ package org.hibernate.query;
import org.hibernate.query.criteria.JpaCriteriaInsert; import org.hibernate.query.criteria.JpaCriteriaInsert;
import org.hibernate.query.criteria.JpaCriteriaInsertSelect; import org.hibernate.query.criteria.JpaCriteriaInsertSelect;
import jakarta.persistence.TypedQueryReference;
import jakarta.persistence.criteria.CriteriaDelete; import jakarta.persistence.criteria.CriteriaDelete;
import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.CriteriaUpdate; import jakarta.persistence.criteria.CriteriaUpdate;
@ -105,6 +106,22 @@ public interface QueryProducer {
*/ */
<R> Query<R> createQuery(String queryString, Class<R> resultClass); <R> Query<R> createQuery(String queryString, Class<R> resultClass);
/**
* Create a typed {@link Query} instance for the given typed query reference.
*
* @param typedQueryReference the type query reference
*
* @return The {@link Query} instance for execution
*
* @throws IllegalArgumentException if a query has not been
* defined with the name of the typed query reference or if
* the query result is found to not be assignable to
* result class of the typed query reference
*
* @see jakarta.persistence.EntityManager#createQuery(TypedQueryReference)
*/
<R> Query<R> createQuery(TypedQueryReference<R> typedQueryReference);
/** /**
* Create a {@link Query} for the given JPA {@link CriteriaQuery}. * Create a {@link Query} for the given JPA {@link CriteriaQuery}.
*/ */

View File

@ -22,9 +22,12 @@ import org.hibernate.query.sqm.internal.SqmSelectionQueryImpl;
import org.hibernate.query.sqm.spi.NamedSqmQueryMemento; import org.hibernate.query.sqm.spi.NamedSqmQueryMemento;
import org.hibernate.query.sqm.tree.SqmStatement; import org.hibernate.query.sqm.tree.SqmStatement;
public class NamedCriteriaQueryMementoImpl extends AbstractNamedQueryMemento implements NamedSqmQueryMemento, Serializable { import org.checkerframework.checker.nullness.qual.Nullable;
private final SqmStatement sqmStatement; public class NamedCriteriaQueryMementoImpl<E> extends AbstractNamedQueryMemento<E>
implements NamedSqmQueryMemento<E>, Serializable {
private final SqmStatement<E> sqmStatement;
private final Integer firstResult; private final Integer firstResult;
private final Integer maxResults; private final Integer maxResults;
@ -33,7 +36,8 @@ public class NamedCriteriaQueryMementoImpl extends AbstractNamedQueryMemento imp
public NamedCriteriaQueryMementoImpl( public NamedCriteriaQueryMementoImpl(
String name, String name,
SqmStatement sqmStatement, @Nullable Class<E> resultType,
SqmStatement<E> sqmStatement,
Integer firstResult, Integer firstResult,
Integer maxResults, Integer maxResults,
Boolean cacheable, Boolean cacheable,
@ -47,7 +51,7 @@ public class NamedCriteriaQueryMementoImpl extends AbstractNamedQueryMemento imp
String comment, String comment,
Map<String, String> parameterTypes, Map<String, String> parameterTypes,
Map<String, Object> hints) { Map<String, Object> hints) {
super( name, cacheable, cacheRegion, cacheMode, flushMode, readOnly, timeout, fetchSize, comment, hints ); super( name, resultType, cacheable, cacheRegion, cacheMode, flushMode, readOnly, timeout, fetchSize, comment, hints );
this.sqmStatement = sqmStatement; this.sqmStatement = sqmStatement;
this.firstResult = firstResult; this.firstResult = firstResult;
this.maxResults = maxResults; this.maxResults = maxResults;
@ -67,8 +71,8 @@ public class NamedCriteriaQueryMementoImpl extends AbstractNamedQueryMemento imp
} }
@Override @Override
public <T> SqmQueryImplementor<T> toQuery(SharedSessionContractImplementor session) { public SqmQueryImplementor<E> toQuery(SharedSessionContractImplementor session) {
return toQuery(session, null); return toQuery( session, getResultType() );
} }
@Override @Override
@ -86,7 +90,7 @@ public class NamedCriteriaQueryMementoImpl extends AbstractNamedQueryMemento imp
} }
@Override @Override
public SqmStatement<?> getSqmStatement() { public SqmStatement<E> getSqmStatement() {
return sqmStatement; return sqmStatement;
} }
@ -111,9 +115,10 @@ public class NamedCriteriaQueryMementoImpl extends AbstractNamedQueryMemento imp
} }
@Override @Override
public NamedSqmQueryMemento makeCopy(String name) { public NamedSqmQueryMemento<E> makeCopy(String name) {
return new NamedCriteriaQueryMementoImpl( return new NamedCriteriaQueryMementoImpl<E>(
name, name,
getResultType(),
sqmStatement, sqmStatement,
firstResult, firstResult,
maxResults, maxResults,

View File

@ -22,6 +22,10 @@ import org.hibernate.query.sqm.internal.SqmSelectionQueryImpl;
import org.hibernate.query.sqm.spi.NamedSqmQueryMemento; import org.hibernate.query.sqm.spi.NamedSqmQueryMemento;
import org.hibernate.query.sqm.tree.SqmStatement; import org.hibernate.query.sqm.tree.SqmStatement;
import org.jboss.logging.Logger;
import org.checkerframework.checker.nullness.qual.Nullable;
/** /**
* Definition of a named query, defined in the mapping metadata. * Definition of a named query, defined in the mapping metadata.
* Additionally, as of JPA 2.1, named query definition can also come * Additionally, as of JPA 2.1, named query definition can also come
@ -30,7 +34,8 @@ import org.hibernate.query.sqm.tree.SqmStatement;
* @author Gavin King * @author Gavin King
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class NamedHqlQueryMementoImpl extends AbstractNamedQueryMemento implements NamedSqmQueryMemento, Serializable { public class NamedHqlQueryMementoImpl<R> extends AbstractNamedQueryMemento<R>
implements NamedSqmQueryMemento<R>, Serializable {
private final String hqlString; private final String hqlString;
private final Integer firstResult; private final Integer firstResult;
@ -41,6 +46,7 @@ public class NamedHqlQueryMementoImpl extends AbstractNamedQueryMemento implemen
public NamedHqlQueryMementoImpl( public NamedHqlQueryMementoImpl(
String name, String name,
@Nullable Class<R> resultType,
String hqlString, String hqlString,
Integer firstResult, Integer firstResult,
Integer maxResults, Integer maxResults,
@ -57,6 +63,7 @@ public class NamedHqlQueryMementoImpl extends AbstractNamedQueryMemento implemen
Map<String,Object> hints) { Map<String,Object> hints) {
super( super(
name, name,
resultType,
cacheable, cacheable,
cacheRegion, cacheRegion,
cacheMode, cacheMode,
@ -100,9 +107,10 @@ public class NamedHqlQueryMementoImpl extends AbstractNamedQueryMemento implemen
} }
@Override @Override
public NamedSqmQueryMemento makeCopy(String name) { public NamedSqmQueryMemento<R> makeCopy(String name) {
return new NamedHqlQueryMementoImpl( return new NamedHqlQueryMementoImpl<>(
name, name,
getResultType(),
hqlString, hqlString,
firstResult, firstResult,
maxResults, maxResults,
@ -122,12 +130,12 @@ public class NamedHqlQueryMementoImpl extends AbstractNamedQueryMemento implemen
@Override @Override
public void validate(QueryEngine queryEngine) { public void validate(QueryEngine queryEngine) {
queryEngine.getHqlTranslator().translate( hqlString, null ); queryEngine.getHqlTranslator().translate( hqlString, getResultType() );
} }
@Override @Override
public <T> SqmQueryImplementor<T> toQuery(SharedSessionContractImplementor session) { public SqmQueryImplementor<R> toQuery(SharedSessionContractImplementor session) {
return toQuery( session, null ); return toQuery( session, getResultType() );
} }
@Override @Override
@ -140,7 +148,7 @@ public class NamedHqlQueryMementoImpl extends AbstractNamedQueryMemento implemen
} }
@Override @Override
public SqmStatement<?> getSqmStatement() { public SqmStatement<R> getSqmStatement() {
return null; return null;
} }

View File

@ -42,7 +42,7 @@ import jakarta.persistence.TemporalType;
*/ */
public interface SqmQueryImplementor<R> extends QueryImplementor<R>, SqmQuery, NameableQuery { public interface SqmQueryImplementor<R> extends QueryImplementor<R>, SqmQuery, NameableQuery {
@Override @Override
NamedQueryMemento toMemento(String name); NamedQueryMemento<R> toMemento(String name);
@Override @Override
ParameterMetadataImplementor getParameterMetadata(); ParameterMetadataImplementor getParameterMetadata();

View File

@ -35,6 +35,8 @@ import org.hibernate.query.sqm.spi.NamedSqmQueryMemento;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import jakarta.persistence.TypedQueryReference;
import static org.hibernate.query.QueryLogging.QUERY_MESSAGE_LOGGER; import static org.hibernate.query.QueryLogging.QUERY_MESSAGE_LOGGER;
/** /**
@ -43,14 +45,14 @@ import static org.hibernate.query.QueryLogging.QUERY_MESSAGE_LOGGER;
public class NamedObjectRepositoryImpl implements NamedObjectRepository { public class NamedObjectRepositoryImpl implements NamedObjectRepository {
private static final Logger log = Logger.getLogger( NamedObjectRepository.class ); private static final Logger log = Logger.getLogger( NamedObjectRepository.class );
private final Map<String, NamedSqmQueryMemento> sqmMementoMap; private final Map<String, NamedSqmQueryMemento<?>> sqmMementoMap;
private final Map<String, NamedNativeQueryMemento> sqlMementoMap; private final Map<String, NamedNativeQueryMemento<?>> sqlMementoMap;
private final Map<String, NamedCallableQueryMemento> callableMementoMap; private final Map<String, NamedCallableQueryMemento> callableMementoMap;
private final Map<String, NamedResultSetMappingMemento> resultSetMappingMementoMap; private final Map<String, NamedResultSetMappingMemento> resultSetMappingMementoMap;
public NamedObjectRepositoryImpl( public NamedObjectRepositoryImpl(
Map<String,NamedSqmQueryMemento> sqmMementoMap, Map<String,NamedSqmQueryMemento<?>> sqmMementoMap,
Map<String,NamedNativeQueryMemento> sqlMementoMap, Map<String,NamedNativeQueryMemento<?>> sqlMementoMap,
Map<String,NamedCallableQueryMemento> callableMementoMap, Map<String,NamedCallableQueryMemento> callableMementoMap,
Map<String,NamedResultSetMappingMemento> resultSetMappingMementoMap) { Map<String,NamedResultSetMappingMemento> resultSetMappingMementoMap) {
this.sqmMementoMap = sqmMementoMap; this.sqmMementoMap = sqmMementoMap;
@ -59,22 +61,38 @@ public class NamedObjectRepositoryImpl implements NamedObjectRepository {
this.resultSetMappingMementoMap = resultSetMappingMementoMap; this.resultSetMappingMementoMap = resultSetMappingMementoMap;
} }
@Override
@SuppressWarnings("unchecked")
public <R> Map<String, TypedQueryReference<R>> getNamedQueries(Class<R> resultType) {
final Map<String, TypedQueryReference<R>> namedQueries = new HashMap<>( sqmMementoMap.size() + sqlMementoMap.size() );
for ( Map.Entry<String, NamedSqmQueryMemento<?>> entry : sqmMementoMap.entrySet() ) {
if ( resultType == entry.getValue().getResultType() ) {
namedQueries.put( entry.getKey(), (TypedQueryReference<R>) entry.getValue() );
}
}
for ( Map.Entry<String, NamedNativeQueryMemento<?>> entry : sqlMementoMap.entrySet() ) {
if ( resultType == entry.getValue().getResultType() ) {
namedQueries.put( entry.getKey(), (TypedQueryReference<R>) entry.getValue() );
}
}
return namedQueries;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Named SQM Memento // Named SQM Memento
@Override @Override
public NamedSqmQueryMemento getSqmQueryMemento(String queryName) { public NamedSqmQueryMemento<?> getSqmQueryMemento(String queryName) {
return sqmMementoMap.get( queryName ); return sqmMementoMap.get( queryName );
} }
@Override @Override
public void visitSqmQueryMementos(Consumer<NamedSqmQueryMemento> action) { public void visitSqmQueryMementos(Consumer<NamedSqmQueryMemento<?>> action) {
sqmMementoMap.values().forEach( action ); sqmMementoMap.values().forEach( action );
} }
@Override @Override
public void registerSqmQueryMemento(String name, NamedSqmQueryMemento descriptor) { public void registerSqmQueryMemento(String name, NamedSqmQueryMemento<?> descriptor) {
sqmMementoMap.put( name, descriptor ); sqmMementoMap.put( name, descriptor );
sqlMementoMap.remove( name ); sqlMementoMap.remove( name );
} }
@ -83,17 +101,17 @@ public class NamedObjectRepositoryImpl implements NamedObjectRepository {
// SQL mementos // SQL mementos
@Override @Override
public NamedNativeQueryMemento getNativeQueryMemento(String queryName) { public NamedNativeQueryMemento<?> getNativeQueryMemento(String queryName) {
return sqlMementoMap.get( queryName ); return sqlMementoMap.get( queryName );
} }
@Override @Override
public void visitNativeQueryMementos(Consumer<NamedNativeQueryMemento> action) { public void visitNativeQueryMementos(Consumer<NamedNativeQueryMemento<?>> action) {
sqlMementoMap.values().forEach( action ); sqlMementoMap.values().forEach( action );
} }
@Override @Override
public synchronized void registerNativeQueryMemento(String name, NamedNativeQueryMemento descriptor) { public synchronized void registerNativeQueryMemento(String name, NamedNativeQueryMemento<?> descriptor) {
sqlMementoMap.put( name, descriptor ); sqlMementoMap.put( name, descriptor );
sqmMementoMap.remove( name ); sqmMementoMap.remove( name );
} }
@ -141,11 +159,11 @@ public class NamedObjectRepositoryImpl implements NamedObjectRepository {
// Prepare repository for use // Prepare repository for use
@Override @Override
public NamedQueryMemento resolve( public NamedQueryMemento<?> resolve(
SessionFactoryImplementor sessionFactory, SessionFactoryImplementor sessionFactory,
MetadataImplementor bootMetamodel, MetadataImplementor bootMetamodel,
String registrationName) { String registrationName) {
NamedQueryMemento namedQuery = sqlMementoMap.get( registrationName ); NamedQueryMemento<?> namedQuery = sqlMementoMap.get( registrationName );
if ( namedQuery != null ) { if ( namedQuery != null ) {
return namedQuery; return namedQuery;
} }
@ -157,15 +175,15 @@ public class NamedObjectRepositoryImpl implements NamedObjectRepository {
if ( namedQuery != null ) { if ( namedQuery != null ) {
return namedQuery; return namedQuery;
} }
final NamedHqlQueryDefinition namedHqlQueryDefinition = bootMetamodel.getNamedHqlQueryMapping( registrationName ); final NamedHqlQueryDefinition<?> namedHqlQueryDefinition = bootMetamodel.getNamedHqlQueryMapping( registrationName );
if ( namedHqlQueryDefinition != null ) { if ( namedHqlQueryDefinition != null ) {
final NamedSqmQueryMemento resolved = namedHqlQueryDefinition.resolve( sessionFactory ); final NamedSqmQueryMemento<?> resolved = namedHqlQueryDefinition.resolve( sessionFactory );
sqmMementoMap.put( namedHqlQueryDefinition.getRegistrationName(), resolved ); sqmMementoMap.put( namedHqlQueryDefinition.getRegistrationName(), resolved );
return resolved; return resolved;
} }
final NamedNativeQueryDefinition namedNativeQueryDefinition = bootMetamodel.getNamedNativeQueryMapping( registrationName ); final NamedNativeQueryDefinition<?> namedNativeQueryDefinition = bootMetamodel.getNamedNativeQueryMapping( registrationName );
if ( namedNativeQueryDefinition != null ) { if ( namedNativeQueryDefinition != null ) {
final NamedNativeQueryMemento resolved = namedNativeQueryDefinition.resolve( sessionFactory ); final NamedNativeQueryMemento<?> resolved = namedNativeQueryDefinition.resolve( sessionFactory );
sqlMementoMap.put( namedNativeQueryDefinition.getRegistrationName(), resolved ); sqlMementoMap.put( namedNativeQueryDefinition.getRegistrationName(), resolved );
return resolved; return resolved;
} }
@ -182,14 +200,14 @@ public class NamedObjectRepositoryImpl implements NamedObjectRepository {
public void prepare(SessionFactoryImplementor sessionFactory, Metadata bootMetamodel) { public void prepare(SessionFactoryImplementor sessionFactory, Metadata bootMetamodel) {
bootMetamodel.visitNamedHqlQueryDefinitions( bootMetamodel.visitNamedHqlQueryDefinitions(
namedHqlQueryDefinition -> { namedHqlQueryDefinition -> {
final NamedSqmQueryMemento resolved = namedHqlQueryDefinition.resolve( sessionFactory ); final NamedSqmQueryMemento<?> resolved = namedHqlQueryDefinition.resolve( sessionFactory );
sqmMementoMap.put( namedHqlQueryDefinition.getRegistrationName(), resolved ); sqmMementoMap.put( namedHqlQueryDefinition.getRegistrationName(), resolved );
} }
); );
bootMetamodel.visitNamedNativeQueryDefinitions( bootMetamodel.visitNamedNativeQueryDefinitions(
namedNativeQueryDefinition -> { namedNativeQueryDefinition -> {
final NamedNativeQueryMemento resolved = namedNativeQueryDefinition.resolve( sessionFactory ); final NamedNativeQueryMemento<?> resolved = namedNativeQueryDefinition.resolve( sessionFactory );
sqlMementoMap.put( namedNativeQueryDefinition.getRegistrationName(), resolved ); sqlMementoMap.put( namedNativeQueryDefinition.getRegistrationName(), resolved );
} }
); );
@ -241,7 +259,7 @@ public class NamedObjectRepositoryImpl implements NamedObjectRepository {
// Check named HQL queries // Check named HQL queries
log.debugf( "Checking %s named HQL queries", sqmMementoMap.size() ); log.debugf( "Checking %s named HQL queries", sqmMementoMap.size() );
for ( NamedSqmQueryMemento hqlMemento : sqmMementoMap.values() ) { for ( NamedSqmQueryMemento<?> hqlMemento : sqmMementoMap.values() ) {
final String queryString = hqlMemento.getHqlString(); final String queryString = hqlMemento.getHqlString();
final String registrationName = hqlMemento.getRegistrationName(); final String registrationName = hqlMemento.getRegistrationName();
try { try {
@ -265,7 +283,7 @@ public class NamedObjectRepositoryImpl implements NamedObjectRepository {
// Check native-sql queries // Check native-sql queries
log.debugf( "Checking %s named SQL queries", sqlMementoMap.size() ); log.debugf( "Checking %s named SQL queries", sqlMementoMap.size() );
for ( NamedNativeQueryMemento memento : sqlMementoMap.values() ) { for ( NamedNativeQueryMemento<?> memento : sqlMementoMap.values() ) {
memento.validate( queryEngine ); memento.validate( queryEngine );
// // this will throw an error if there's something wrong. // // this will throw an error if there's something wrong.
// try { // try {

View File

@ -6,20 +6,20 @@
*/ */
package org.hibernate.query.named; package org.hibernate.query.named;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set;
import org.hibernate.CacheMode; import org.hibernate.CacheMode;
import org.hibernate.FlushMode; import org.hibernate.FlushMode;
import org.checkerframework.checker.nullness.qual.Nullable;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
* @author Gavin King * @author Gavin King
*/ */
public abstract class AbstractNamedQueryMemento implements NamedQueryMemento { public abstract class AbstractNamedQueryMemento<R> implements NamedQueryMemento<R> {
private final String name; private final String name;
private final @Nullable Class<R> resultType;
private final Boolean cacheable; private final Boolean cacheable;
private final String cacheRegion; private final String cacheRegion;
@ -37,6 +37,7 @@ public abstract class AbstractNamedQueryMemento implements NamedQueryMemento {
protected AbstractNamedQueryMemento( protected AbstractNamedQueryMemento(
String name, String name,
@Nullable Class<R> resultType,
Boolean cacheable, Boolean cacheable,
String cacheRegion, String cacheRegion,
CacheMode cacheMode, CacheMode cacheMode,
@ -47,6 +48,7 @@ public abstract class AbstractNamedQueryMemento implements NamedQueryMemento {
String comment, String comment,
Map<String, Object> hints) { Map<String, Object> hints) {
this.name = name; this.name = name;
this.resultType = resultType;
this.cacheable = cacheable; this.cacheable = cacheable;
this.cacheRegion = cacheRegion; this.cacheRegion = cacheRegion;
this.cacheMode = cacheMode; this.cacheMode = cacheMode;
@ -63,6 +65,11 @@ public abstract class AbstractNamedQueryMemento implements NamedQueryMemento {
return name; return name;
} }
@Override
public @Nullable Class<R> getResultType() {
return resultType;
}
@Override @Override
public Boolean getCacheable() { public Boolean getCacheable() {
return cacheable; return cacheable;
@ -108,141 +115,4 @@ public abstract class AbstractNamedQueryMemento implements NamedQueryMemento {
return hints; return hints;
} }
public static abstract class AbstractBuilder<T extends AbstractBuilder> {
protected final String name;
protected Set<String> querySpaces;
protected Boolean cacheable;
protected String cacheRegion;
protected CacheMode cacheMode;
protected FlushMode flushMode;
protected Boolean readOnly;
protected Integer timeout;
protected Integer fetchSize;
protected String comment;
protected Map<String,Object> hints;
public AbstractBuilder(String name) {
this.name = name;
}
public String getName() {
return name;
}
protected abstract T getThis();
public T addQuerySpaces(Set<String> querySpaces) {
if ( querySpaces == null || querySpaces.isEmpty() ) {
return getThis();
}
if ( this.querySpaces == null ) {
this.querySpaces = new HashSet<>();
}
this.querySpaces.addAll( querySpaces );
return getThis();
}
public T addQuerySpace(String space) {
if ( this.querySpaces == null ) {
this.querySpaces = new HashSet<>();
}
this.querySpaces.add( space );
return getThis();
}
public T setCacheable(Boolean cacheable) {
this.cacheable = cacheable;
return getThis();
}
public T setCacheRegion(String cacheRegion) {
this.cacheRegion = cacheRegion;
return getThis();
}
public T setCacheMode(CacheMode cacheMode) {
this.cacheMode = cacheMode;
return getThis();
}
public T setTimeout(Integer timeout) {
this.timeout = timeout;
return getThis();
}
public T setFlushMode(FlushMode flushMode) {
this.flushMode = flushMode;
return getThis();
}
public T setReadOnly(Boolean readOnly) {
this.readOnly = readOnly;
return getThis();
}
public T setReadOnly(boolean readOnly) {
this.readOnly = readOnly;
return getThis();
}
public T setFetchSize(Integer fetchSize) {
this.fetchSize = fetchSize;
return getThis();
}
public T setComment(String comment) {
this.comment = comment;
return getThis();
}
public Set<String> getQuerySpaces() {
return querySpaces;
}
public Boolean getCacheable() {
return cacheable;
}
public String getCacheRegion() {
return cacheRegion;
}
public CacheMode getCacheMode() {
return cacheMode;
}
public FlushMode getFlushMode() {
return flushMode;
}
public Boolean getReadOnly() {
return readOnly;
}
public Integer getTimeout() {
return timeout;
}
public Integer getFetchSize() {
return fetchSize;
}
public String getComment() {
return comment;
}
public void addHint(String name, Object value) {
if ( hints == null ) {
hints = new HashMap<>();
}
hints.put( name, value );
}
}
} }

View File

@ -19,5 +19,5 @@ public interface NameableQuery {
/** /**
* Convert the query into the memento * Convert the query into the memento
*/ */
NamedQueryMemento toMemento(String name); NamedQueryMemento<?> toMemento(String name);
} }

View File

@ -19,6 +19,8 @@ import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sql.spi.NamedNativeQueryMemento; import org.hibernate.query.sql.spi.NamedNativeQueryMemento;
import org.hibernate.query.sqm.spi.NamedSqmQueryMemento; import org.hibernate.query.sqm.spi.NamedSqmQueryMemento;
import jakarta.persistence.TypedQueryReference;
/** /**
* Repository for references to named things related to queries. This includes: * Repository for references to named things related to queries. This includes:
* <ul> * <ul>
@ -31,20 +33,22 @@ import org.hibernate.query.sqm.spi.NamedSqmQueryMemento;
@Incubating @Incubating
public interface NamedObjectRepository { public interface NamedObjectRepository {
<R> Map<String, TypedQueryReference<R>> getNamedQueries(Class<R> resultType);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Named SQM Memento // Named SQM Memento
NamedSqmQueryMemento getSqmQueryMemento(String queryName); NamedSqmQueryMemento<?> getSqmQueryMemento(String queryName);
void visitSqmQueryMementos(Consumer<NamedSqmQueryMemento> action); void visitSqmQueryMementos(Consumer<NamedSqmQueryMemento<?>> action);
void registerSqmQueryMemento(String name, NamedSqmQueryMemento descriptor); void registerSqmQueryMemento(String name, NamedSqmQueryMemento<?> descriptor);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Named NativeQuery Memento // Named NativeQuery Memento
NamedNativeQueryMemento getNativeQueryMemento(String queryName); NamedNativeQueryMemento<?> getNativeQueryMemento(String queryName);
void visitNativeQueryMementos(Consumer<NamedNativeQueryMemento> action); void visitNativeQueryMementos(Consumer<NamedNativeQueryMemento<?>> action);
void registerNativeQueryMemento(String name, NamedNativeQueryMemento descriptor); void registerNativeQueryMemento(String name, NamedNativeQueryMemento<?> descriptor);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -15,6 +15,8 @@ import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.spi.QueryImplementor; import org.hibernate.query.spi.QueryImplementor;
import org.hibernate.query.spi.QueryParameterImplementor; import org.hibernate.query.spi.QueryParameterImplementor;
import jakarta.persistence.TypedQueryReference;
/** /**
* The runtime representation of named queries. They are stored in and * The runtime representation of named queries. They are stored in and
* available through the QueryEngine's {@link NamedObjectRepository}. * available through the QueryEngine's {@link NamedObjectRepository}.
@ -23,12 +25,17 @@ import org.hibernate.query.spi.QueryParameterImplementor;
* *
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public interface NamedQueryMemento { public interface NamedQueryMemento<E> extends TypedQueryReference<E> {
/** /**
* The name under which the query is registered * The name under which the query is registered
*/ */
String getRegistrationName(); String getRegistrationName();
@Override
default String getName() {
return getRegistrationName();
}
Boolean getCacheable(); Boolean getCacheable();
String getCacheRegion(); String getCacheRegion();
@ -52,9 +59,9 @@ public interface NamedQueryMemento {
/** /**
* Makes a copy of the memento using the specified registration name * Makes a copy of the memento using the specified registration name
*/ */
NamedQueryMemento makeCopy(String name); NamedQueryMemento<E> makeCopy(String name);
<T> QueryImplementor<T> toQuery(SharedSessionContractImplementor session); QueryImplementor<E> toQuery(SharedSessionContractImplementor session);
<T> QueryImplementor<T> toQuery(SharedSessionContractImplementor session, Class<T> javaType); <T> QueryImplementor<T> toQuery(SharedSessionContractImplementor session, Class<T> javaType);
interface ParameterMemento { interface ParameterMemento {

View File

@ -81,7 +81,7 @@ public abstract class AbstractQuery<R>
} }
@Override @Override
protected void applyOptions(NamedQueryMemento memento) { protected void applyOptions(NamedQueryMemento<?> memento) {
if ( memento.getHints() != null ) { if ( memento.getHints() != null ) {
memento.getHints().forEach( this::setHint ); memento.getHints().forEach( this::setHint );
} }

View File

@ -81,7 +81,7 @@ public abstract class AbstractSelectionQuery<R>
super( session ); super( session );
} }
protected void applyOptions(NamedQueryMemento memento) { protected void applyOptions(NamedQueryMemento<?> memento) {
if ( memento.getHints() != null ) { if ( memento.getHints() != null ) {
memento.getHints().forEach( this::applyHint ); memento.getHints().forEach( this::applyHint );
} }

View File

@ -13,6 +13,7 @@ import org.hibernate.query.MutationQuery;
import org.hibernate.query.QueryProducer; import org.hibernate.query.QueryProducer;
import org.hibernate.query.sql.spi.NativeQueryImplementor; import org.hibernate.query.sql.spi.NativeQueryImplementor;
import jakarta.persistence.TypedQueryReference;
import jakarta.persistence.criteria.CriteriaDelete; import jakarta.persistence.criteria.CriteriaDelete;
import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.CriteriaUpdate; import jakarta.persistence.criteria.CriteriaUpdate;
@ -38,6 +39,9 @@ public interface QueryProducerImplementor extends QueryProducer {
@Override @Override
<R> QueryImplementor<R> createQuery(String queryString, Class<R> resultClass); <R> QueryImplementor<R> createQuery(String queryString, Class<R> resultClass);
@Override
<R> QueryImplementor<R> createQuery(TypedQueryReference<R> typedQueryReference);
@Override @Deprecated @SuppressWarnings("rawtypes") @Override @Deprecated @SuppressWarnings("rawtypes")
QueryImplementor createNamedQuery(String name); QueryImplementor createNamedQuery(String name);

View File

@ -23,12 +23,11 @@ import org.hibernate.query.sql.spi.NativeQueryImplementor;
* @author Max Andersen * @author Max Andersen
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class NamedNativeQueryMementoImpl extends AbstractNamedQueryMemento implements NamedNativeQueryMemento { public class NamedNativeQueryMementoImpl<E> extends AbstractNamedQueryMemento<E> implements NamedNativeQueryMemento<E> {
private final String sqlString; private final String sqlString;
private final String originalSqlString; private final String originalSqlString;
private final String resultSetMappingName; private final String resultSetMappingName;
private final Class<?> resultSetMappingClass;
private final Set<String> querySpaces; private final Set<String> querySpaces;
@ -38,10 +37,10 @@ public class NamedNativeQueryMementoImpl extends AbstractNamedQueryMemento imple
public NamedNativeQueryMementoImpl( public NamedNativeQueryMementoImpl(
String name, String name,
Class<E> resultClass,
String sqlString, String sqlString,
String originalSqlString, String originalSqlString,
String resultSetMappingName, String resultSetMappingName,
Class<?> resultSetMappingClass,
Set<String> querySpaces, Set<String> querySpaces,
Boolean cacheable, Boolean cacheable,
String cacheRegion, String cacheRegion,
@ -56,6 +55,7 @@ public class NamedNativeQueryMementoImpl extends AbstractNamedQueryMemento imple
Map<String,Object> hints) { Map<String,Object> hints) {
super( super(
name, name,
resultClass,
cacheable, cacheable,
cacheRegion, cacheRegion,
cacheMode, cacheMode,
@ -71,7 +71,6 @@ public class NamedNativeQueryMementoImpl extends AbstractNamedQueryMemento imple
this.resultSetMappingName = resultSetMappingName == null || resultSetMappingName.isEmpty() this.resultSetMappingName = resultSetMappingName == null || resultSetMappingName.isEmpty()
? null ? null
: resultSetMappingName; : resultSetMappingName;
this.resultSetMappingClass = resultSetMappingClass;
this.querySpaces = querySpaces; this.querySpaces = querySpaces;
this.firstResult = firstResult; this.firstResult = firstResult;
this.maxResults = maxResults; this.maxResults = maxResults;
@ -81,10 +80,6 @@ public class NamedNativeQueryMementoImpl extends AbstractNamedQueryMemento imple
return resultSetMappingName; return resultSetMappingName;
} }
public Class<?> getResultSetMappingClass() {
return resultSetMappingClass;
}
public Set<String> getQuerySpaces() { public Set<String> getQuerySpaces() {
return querySpaces; return querySpaces;
} }
@ -104,11 +99,6 @@ public class NamedNativeQueryMementoImpl extends AbstractNamedQueryMemento imple
return resultSetMappingName; return resultSetMappingName;
} }
@Override
public Class<?> getResultMappingClass() {
return resultSetMappingClass;
}
@Override @Override
public Integer getFirstResult() { public Integer getFirstResult() {
return firstResult; return firstResult;
@ -120,13 +110,13 @@ public class NamedNativeQueryMementoImpl extends AbstractNamedQueryMemento imple
} }
@Override @Override
public NamedNativeQueryMemento makeCopy(String name) { public NamedNativeQueryMemento<E> makeCopy(String name) {
return new NamedNativeQueryMementoImpl( return new NamedNativeQueryMementoImpl<>(
name, name,
getResultType(),
sqlString, sqlString,
originalSqlString, originalSqlString,
resultSetMappingName, resultSetMappingName,
resultSetMappingClass,
querySpaces, querySpaces,
getCacheable(), getCacheable(),
getCacheRegion(), getCacheRegion(),
@ -148,8 +138,8 @@ public class NamedNativeQueryMementoImpl extends AbstractNamedQueryMemento imple
} }
@Override @Override
public <T> NativeQueryImplementor<T> toQuery(SharedSessionContractImplementor session) { public NativeQueryImplementor<E> toQuery(SharedSessionContractImplementor session) {
return new NativeQueryImpl<>( this, session ); return new NativeQueryImpl<>( this, getResultType(), session );
} }
@Override @Override

View File

@ -140,7 +140,7 @@ public class NativeQueryImpl<R>
* Constructs a NativeQueryImpl given a sql query defined in the mappings. * Constructs a NativeQueryImpl given a sql query defined in the mappings.
*/ */
public NativeQueryImpl( public NativeQueryImpl(
NamedNativeQueryMemento memento, NamedNativeQueryMemento<?> memento,
SharedSessionContractImplementor session) { SharedSessionContractImplementor session) {
this( this(
memento, memento,
@ -148,8 +148,8 @@ public class NativeQueryImpl<R>
if ( memento.getResultMappingName() != null ) { if ( memento.getResultMappingName() != null ) {
return buildResultSetMapping( memento.getResultMappingName(), false, session ); return buildResultSetMapping( memento.getResultMappingName(), false, session );
} }
else if ( memento.getResultMappingClass() != null ) { else if ( memento.getResultType() != null ) {
return buildResultSetMapping( memento.getResultMappingClass().getName(), false, session ); return buildResultSetMapping( memento.getResultType().getName(), false, session );
} }
return buildResultSetMapping( memento.getSqlString(), false, session ); return buildResultSetMapping( memento.getSqlString(), false, session );
@ -166,10 +166,10 @@ public class NativeQueryImpl<R>
} }
} }
if ( memento.getResultMappingClass() != null ) { if ( memento.getResultType() != null ) {
resultSetMapping.addResultBuilder( resultSetMapping.addResultBuilder(
resultClassBuilder( resultClassBuilder(
memento.getResultMappingClass(), memento.getResultType(),
context context
) )
); );
@ -186,7 +186,7 @@ public class NativeQueryImpl<R>
* Constructs a NativeQueryImpl given a sql query defined in the mappings. * Constructs a NativeQueryImpl given a sql query defined in the mappings.
*/ */
public NativeQueryImpl( public NativeQueryImpl(
NamedNativeQueryMemento memento, NamedNativeQueryMemento<?> memento,
Class<R> resultJavaType, Class<R> resultJavaType,
SharedSessionContractImplementor session) { SharedSessionContractImplementor session) {
this( this(
@ -207,9 +207,9 @@ public class NativeQueryImpl<R>
} }
} }
if ( memento.getResultMappingClass() != null ) { if ( memento.getResultType() != null ) {
resultSetMapping.addResultBuilder( resultClassBuilder( resultSetMapping.addResultBuilder( resultClassBuilder(
memento.getResultMappingClass(), memento.getResultType(),
context context
) ); ) );
return true; return true;
@ -246,7 +246,7 @@ public class NativeQueryImpl<R>
* Constructs a NativeQueryImpl given a sql query defined in the mappings. * Constructs a NativeQueryImpl given a sql query defined in the mappings.
*/ */
public NativeQueryImpl( public NativeQueryImpl(
NamedNativeQueryMemento memento, NamedNativeQueryMemento<?> memento,
String resultSetMappingName, String resultSetMappingName,
SharedSessionContractImplementor session) { SharedSessionContractImplementor session) {
this( this(
@ -267,7 +267,7 @@ public class NativeQueryImpl<R>
} }
public NativeQueryImpl( public NativeQueryImpl(
NamedNativeQueryMemento memento, NamedNativeQueryMemento<?> memento,
Supplier<ResultSetMapping> resultSetMappingCreator, Supplier<ResultSetMapping> resultSetMappingCreator,
ResultSetMappingHandler resultSetMappingHandler, ResultSetMappingHandler resultSetMappingHandler,
SharedSessionContractImplementor session) { SharedSessionContractImplementor session) {
@ -381,7 +381,7 @@ public class NativeQueryImpl<R>
); );
} }
protected void applyOptions(NamedNativeQueryMemento memento) { protected void applyOptions(NamedNativeQueryMemento<?> memento) {
super.applyOptions( memento ); super.applyOptions( memento );
if ( memento.getMaxResults() != null ) { if ( memento.getMaxResults() != null ) {
@ -458,13 +458,13 @@ public class NativeQueryImpl<R>
} }
@Override @Override
public NamedNativeQueryMemento toMemento(String name) { public NamedNativeQueryMemento<?> toMemento(String name) {
return new NamedNativeQueryMementoImpl( return new NamedNativeQueryMementoImpl<>(
name, name,
extractResultClass( resultSetMapping ),
sqlString, sqlString,
originalSqlString, originalSqlString,
resultSetMapping.getMappingIdentifier(), resultSetMapping.getMappingIdentifier(),
extractResultClass( resultSetMapping ),
querySpaces, querySpaces,
isCacheable(), isCacheable(),
getCacheRegion(), getCacheRegion(),

View File

@ -8,22 +8,17 @@ package org.hibernate.query.sql.spi;
import java.util.Set; import java.util.Set;
import jakarta.persistence.SqlResultSetMapping;
import org.hibernate.boot.query.NamedNativeQueryDefinition;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.query.named.AbstractNamedQueryMemento;
import org.hibernate.query.named.NamedQueryMemento; import org.hibernate.query.named.NamedQueryMemento;
import org.hibernate.query.sql.internal.NamedNativeQueryMementoImpl;
import jakarta.persistence.SqlResultSetMapping;
/** /**
* Descriptor for a named native query in the runtime environment * Descriptor for a named native query in the runtime environment
* *
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public interface NamedNativeQueryMemento extends NamedQueryMemento { public interface NamedNativeQueryMemento<E> extends NamedQueryMemento<E> {
/** /**
* Informational access to the SQL query string * Informational access to the SQL query string
*/ */
@ -48,7 +43,9 @@ public interface NamedNativeQueryMemento extends NamedQueryMemento {
/** /**
* An implicit entity mapping by entity class * An implicit entity mapping by entity class
*/ */
Class<?> getResultMappingClass(); default Class<?> getResultMappingClass() {
return getResultType();
}
Integer getFirstResult(); Integer getFirstResult();
@ -58,7 +55,7 @@ public interface NamedNativeQueryMemento extends NamedQueryMemento {
* Convert the memento into an untyped executable query * Convert the memento into an untyped executable query
*/ */
@Override @Override
<T> NativeQueryImplementor<T> toQuery(SharedSessionContractImplementor session); NativeQueryImplementor<E> toQuery(SharedSessionContractImplementor session);
/** /**
* Convert the memento into a typed executable query * Convert the memento into a typed executable query
@ -72,88 +69,6 @@ public interface NamedNativeQueryMemento extends NamedQueryMemento {
<T> NativeQueryImplementor<T> toQuery(SharedSessionContractImplementor session, String resultSetMapping); <T> NativeQueryImplementor<T> toQuery(SharedSessionContractImplementor session, String resultSetMapping);
@Override @Override
NamedNativeQueryMemento makeCopy(String name); NamedNativeQueryMemento<E> makeCopy(String name);
/**
* Delegate used in creating named HQL query mementos.
*
* @see NamedNativeQueryDefinition
*/
class Builder extends AbstractNamedQueryMemento.AbstractBuilder<Builder> {
protected String queryString;
protected Integer firstResult;
protected Integer maxResults;
protected Set<String> querySpaces;
protected String resultSetMappingName;
protected String resultSetMappingClassName;
public Builder(String name) {
super( name );
}
@Override
protected Builder getThis() {
return this;
}
public Builder setQuery(String queryString) {
this.queryString = queryString;
return this;
}
public Builder setCacheable(boolean cacheable) {
this.cacheable = cacheable;
return this;
}
public Builder setFirstResult(Integer firstResult) {
this.firstResult = firstResult;
return this;
}
public Builder setMaxResults(Integer maxResults) {
this.maxResults = maxResults;
return this;
}
public void setQuerySpaces(Set<String> querySpaces) {
this.querySpaces = querySpaces;
}
public void setResultSetMappingName(String resultSetMappingName) {
this.resultSetMappingName = resultSetMappingName;
}
public void setResultSetMappingClassName(String resultSetMappingClassName) {
this.resultSetMappingClassName = resultSetMappingClassName;
}
public NamedNativeQueryMemento build(SessionFactoryImplementor sessionFactory) {
return new NamedNativeQueryMementoImpl(
name,
queryString,
queryString,
resultSetMappingName,
sessionFactory.getServiceRegistry()
.requireService( ClassLoaderService.class )
.classForName( resultSetMappingClassName ),
querySpaces,
cacheable,
cacheRegion,
cacheMode,
flushMode,
readOnly,
timeout,
fetchSize,
comment,
firstResult,
maxResults,
hints
);
}
}
} }

View File

@ -61,7 +61,7 @@ public interface NativeQueryImplementor<R> extends QueryImplementor<R>, NativeQu
} }
@Override @Override
NamedNativeQueryMemento toMemento(String name); NamedNativeQueryMemento<?> toMemento(String name);
@Override @Override
NativeQueryImplementor<R> addScalar(String columnAlias); NativeQueryImplementor<R> addScalar(String columnAlias);

View File

@ -142,7 +142,7 @@ public class QuerySqmImpl<R>
* Creates a Query instance from a named HQL memento * Creates a Query instance from a named HQL memento
*/ */
public QuerySqmImpl( public QuerySqmImpl(
NamedHqlQueryMementoImpl memento, NamedHqlQueryMementoImpl<?> memento,
Class<R> expectedResultType, Class<R> expectedResultType,
SharedSessionContractImplementor session) { SharedSessionContractImplementor session) {
this( this(
@ -155,7 +155,7 @@ public class QuerySqmImpl<R>
} }
public QuerySqmImpl( public QuerySqmImpl(
NamedCriteriaQueryMementoImpl memento, NamedCriteriaQueryMementoImpl<?> memento,
Class<R> resultType, Class<R> resultType,
SharedSessionContractImplementor session) { SharedSessionContractImplementor session) {
this( (SqmStatement<R>) memento.getSqmStatement(), resultType, session ); this( (SqmStatement<R>) memento.getSqmStatement(), resultType, session );
@ -892,7 +892,7 @@ public class QuerySqmImpl<R>
// Named query externalization // Named query externalization
@Override @Override
public NamedQueryMemento toMemento(String name) { public NamedQueryMemento<R> toMemento(String name) {
if ( CRITERIA_HQL_STRING.equals( getQueryString() ) ) { if ( CRITERIA_HQL_STRING.equals( getQueryString() ) ) {
final SqmStatement<R> sqmStatement; final SqmStatement<R> sqmStatement;
if ( !getSession().isCriteriaCopyTreeEnabled() ) { if ( !getSession().isCriteriaCopyTreeEnabled() ) {
@ -902,8 +902,9 @@ public class QuerySqmImpl<R>
// the statement has already been copied // the statement has already been copied
sqmStatement = getSqmStatement(); sqmStatement = getSqmStatement();
} }
return new NamedCriteriaQueryMementoImpl( return new NamedCriteriaQueryMementoImpl<>(
name, name,
getResultType(),
sqmStatement, sqmStatement,
getQueryOptions().getLimit().getFirstRow(), getQueryOptions().getLimit().getFirstRow(),
getQueryOptions().getLimit().getMaxRows(), getQueryOptions().getLimit().getMaxRows(),
@ -921,8 +922,9 @@ public class QuerySqmImpl<R>
); );
} }
return new NamedHqlQueryMementoImpl( return new NamedHqlQueryMementoImpl<>(
name, name,
getResultType(),
getQueryString(), getQueryString(),
getQueryOptions().getLimit().getFirstRow(), getQueryOptions().getLimit().getFirstRow(),
getQueryOptions().getLimit().getMaxRows(), getQueryOptions().getLimit().getMaxRows(),

View File

@ -114,7 +114,7 @@ public class SqmSelectionQueryImpl<R> extends AbstractSqmSelectionQuery<R>
} }
public SqmSelectionQueryImpl( public SqmSelectionQueryImpl(
NamedHqlQueryMementoImpl memento, NamedHqlQueryMementoImpl<?> memento,
Class<R> resultType, Class<R> resultType,
SharedSessionContractImplementor session) { SharedSessionContractImplementor session) {
this( this(
@ -128,7 +128,7 @@ public class SqmSelectionQueryImpl<R> extends AbstractSqmSelectionQuery<R>
} }
public SqmSelectionQueryImpl( public SqmSelectionQueryImpl(
NamedCriteriaQueryMementoImpl memento, NamedCriteriaQueryMementoImpl<?> memento,
Class<R> expectedResultType, Class<R> expectedResultType,
SharedSessionContractImplementor session) { SharedSessionContractImplementor session) {
//noinspection unchecked //noinspection unchecked

View File

@ -16,19 +16,19 @@ import org.hibernate.query.named.NamedQueryMemento;
import org.hibernate.query.sqm.SqmSelectionQuery; import org.hibernate.query.sqm.SqmSelectionQuery;
import org.hibernate.query.sqm.tree.SqmStatement; import org.hibernate.query.sqm.tree.SqmStatement;
public interface NamedSqmQueryMemento extends NamedQueryMemento { public interface NamedSqmQueryMemento<E> extends NamedQueryMemento<E> {
<T> SqmQueryImplementor<T> toQuery(SharedSessionContractImplementor session, Class<T> resultType); <T> SqmQueryImplementor<T> toQuery(SharedSessionContractImplementor session, Class<T> resultType);
/** /**
* Convert the memento into an untyped executable query * Convert the memento into an untyped executable query
*/ */
<T> SqmQueryImplementor<T> toQuery(SharedSessionContractImplementor session); SqmQueryImplementor<E> toQuery(SharedSessionContractImplementor session);
<T> SqmSelectionQuery<T> toSelectionQuery(Class<T> resultType, SharedSessionContractImplementor session); <T> SqmSelectionQuery<T> toSelectionQuery(Class<T> resultType, SharedSessionContractImplementor session);
String getHqlString(); String getHqlString();
SqmStatement<?> getSqmStatement(); SqmStatement<E> getSqmStatement();
Integer getFirstResult(); Integer getFirstResult();
@ -39,6 +39,6 @@ public interface NamedSqmQueryMemento extends NamedQueryMemento {
Map<String, String> getParameterTypes(); Map<String, String> getParameterTypes();
@Override @Override
NamedSqmQueryMemento makeCopy(String name); NamedSqmQueryMemento<E> makeCopy(String name);
} }

View File

@ -133,7 +133,7 @@ public abstract class AbstractSqmExpression<T> extends AbstractJpaSelection<T> i
} }
@Override @Override
public <X> Expression<X> cast(Class<X> castTarget) { public <X> SqmExpression<X> cast(Class<X> castTarget) {
return nodeBuilder().cast( this, castTarget ); return nodeBuilder().cast( this, castTarget );
} }

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,383 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2008, 2024 Oracle and/or its affiliates. All rights reserved.
This program and the accompanying materials are made available under the
terms of the Eclipse Public License v. 2.0 which is available at
http://www.eclipse.org/legal/epl-2.0,
or the Eclipse Distribution License v. 1.0 which is available at
http://www.eclipse.org/org/documents/edl-v10.php.
SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
-->
<!-- persistence.xml schema -->
<xsd:schema targetNamespace="https://jakarta.ee/xml/ns/persistence"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:persistence="https://jakarta.ee/xml/ns/persistence"
elementFormDefault="qualified"
attributeFormDefault="unqualified"
version="3.2">
<xsd:annotation>
<xsd:documentation><![CDATA[
This is the XML Schema for the persistence configuration file.
The file must be named "META-INF/persistence.xml" in the
persistence archive.
Persistence configuration files must indicate
the persistence schema by using the persistence namespace:
https://jakarta.ee/xml/ns/persistence
and indicate the version of the schema by
using the version element as shown below:
<persistence xmlns="https://jakarta.ee/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence
https://jakarta.ee/xml/ns/persistence/persistence_3_2.xsd"
version="3.2">
...
</persistence>
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType name="versionType">
<xsd:restriction base="xsd:token">
<xsd:pattern value="[0-9]+(\.[0-9]+)*"/>
</xsd:restriction>
</xsd:simpleType>
<!-- **************************************************** -->
<xsd:element name="persistence">
<xsd:complexType>
<xsd:sequence>
<!-- **************************************************** -->
<xsd:element name="persistence-unit"
minOccurs="1" maxOccurs="unbounded">
<xsd:complexType>
<xsd:annotation>
<xsd:documentation>
Configuration of a persistence unit.
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<!-- **************************************************** -->
<xsd:element name="description" type="xsd:string"
minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Description of this persistence unit.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<!-- **************************************************** -->
<xsd:element name="provider" type="xsd:string"
minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Provider class that supplies EntityManagers for this
persistence unit.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<!-- **************************************************** -->
<xsd:element name="qualifier" type="xsd:string"
minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
Qualifier annotation class used for dependency injection.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<!-- **************************************************** -->
<xsd:element name="scope" type="xsd:string"
minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Scope annotation class used for dependency injection.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<!-- **************************************************** -->
<xsd:element name="jta-data-source" type="xsd:string"
minOccurs="0">
<xsd:annotation>
<xsd:documentation>
The container-specific name of the JTA datasource to use.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<!-- **************************************************** -->
<xsd:element name="non-jta-data-source" type="xsd:string"
minOccurs="0">
<xsd:annotation>
<xsd:documentation>
The container-specific name of a non-JTA datasource to use.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<!-- **************************************************** -->
<xsd:element name="mapping-file" type="xsd:string"
minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
File containing mapping information. Loaded as a resource
by the persistence provider.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<!-- **************************************************** -->
<xsd:element name="jar-file" type="xsd:string"
minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
Jar file that is to be scanned for managed classes.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<!-- **************************************************** -->
<xsd:element name="class" type="xsd:string"
minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
Managed class to be included in the persistence unit and
to scan for annotations. It should be annotated
with either @Entity, @Embeddable or @MappedSuperclass.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<!-- **************************************************** -->
<xsd:element name="exclude-unlisted-classes" type="xsd:boolean"
default="true" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
When set to true then only listed classes and jars will
be scanned for persistent classes, otherwise the
enclosing jar or directory will also be scanned.
Not applicable to Java SE persistence units.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<!-- **************************************************** -->
<xsd:element name="shared-cache-mode"
type="persistence:persistence-unit-caching-type"
minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Defines whether caching is enabled for the
persistence unit if caching is supported by the
persistence provider. When set to ALL, all entities
will be cached. When set to NONE, no entities will
be cached. When set to ENABLE_SELECTIVE, only entities
specified as cacheable will be cached. When set to
DISABLE_SELECTIVE, entities specified as not cacheable
will not be cached. When not specified or when set to
UNSPECIFIED, provider defaults may apply.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<!-- **************************************************** -->
<xsd:element name="validation-mode"
type="persistence:persistence-unit-validation-mode-type"
minOccurs="0">
<xsd:annotation>
<xsd:documentation>
The validation mode to be used for the persistence unit.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<!-- **************************************************** -->
<xsd:element name="properties" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
A list of standard and vendor-specific properties
and hints.
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element name="property"
minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
A name-value pair.
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="name" type="xsd:string"
use="required"/>
<xsd:attribute name="value" type="xsd:string"
use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:any namespace="##other" processContents="lax"
minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
An extension point for integration related configuration, e.g. cdi:
<!--
<persistence-unit name="my-unit" xmlns:cdi="https://jakarta.ee/xml/ns/persistence-cdi">
...
<cdi:scope>com.example.jpa.ACustomScope</cdi:scope>
<cdi:qualifier>com.example.jpa.CustomQualifier</cdi:qualifier>
</persistence-unit>
-->
</xsd:documentation>
</xsd:annotation>
</xsd:any>
</xsd:sequence>
<!-- **************************************************** -->
<xsd:attribute name="name" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation>
Name used in code to reference this persistence unit.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<!-- **************************************************** -->
<xsd:attribute name="transaction-type"
type="persistence:persistence-unit-transaction-type">
<xsd:annotation>
<xsd:documentation>
Type of transactions used by EntityManagers from this
persistence unit.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="version" type="persistence:versionType"
fixed="3.2" use="required"/>
</xsd:complexType>
</xsd:element>
<!-- **************************************************** -->
<xsd:simpleType name="persistence-unit-transaction-type">
<xsd:annotation>
<xsd:documentation>
public enum PersistenceUnitTransactionType {JTA, RESOURCE_LOCAL};
</xsd:documentation>
</xsd:annotation>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="JTA"/>
<xsd:enumeration value="RESOURCE_LOCAL"/>
</xsd:restriction>
</xsd:simpleType>
<!-- **************************************************** -->
<xsd:simpleType name="persistence-unit-caching-type">
<xsd:annotation>
<xsd:documentation>
public enum SharedCacheMode { ALL, NONE, ENABLE_SELECTIVE, DISABLE_SELECTIVE, UNSPECIFIED};
</xsd:documentation>
</xsd:annotation>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="ALL"/>
<xsd:enumeration value="NONE"/>
<xsd:enumeration value="ENABLE_SELECTIVE"/>
<xsd:enumeration value="DISABLE_SELECTIVE"/>
<xsd:enumeration value="UNSPECIFIED"/>
</xsd:restriction>
</xsd:simpleType>
<!-- **************************************************** -->
<xsd:simpleType name="persistence-unit-validation-mode-type">
<xsd:annotation>
<xsd:documentation>
public enum ValidationMode { AUTO, CALLBACK, NONE};
</xsd:documentation>
</xsd:annotation>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="AUTO"/>
<xsd:enumeration value="CALLBACK"/>
<xsd:enumeration value="NONE"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>

View File

@ -85,6 +85,32 @@
<!-- **************************************************** --> <!-- **************************************************** -->
<xsd:element name="qualifier" type="xsd:string"
minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
Qualifier annotation class used for dependency injection.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<!-- **************************************************** -->
<xsd:element name="scope" type="xsd:string"
minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Scope annotation class used for dependency injection.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<!-- **************************************************** -->
<xsd:element name="jta-data-source" type="xsd:string" <xsd:element name="jta-data-source" type="xsd:string"
minOccurs="0"> minOccurs="0">
<xsd:annotation> <xsd:annotation>

View File

@ -539,7 +539,7 @@
<xsd:element name="basic" type="orm:basic" <xsd:element name="basic" type="orm:basic"
minOccurs="0" maxOccurs="unbounded"/> minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="version" type="orm:version" <xsd:element name="version" type="orm:version"
minOccurs="0" maxOccurs="unbounded"/> minOccurs="0"/>
<xsd:element name="many-to-one" type="orm:many-to-one" <xsd:element name="many-to-one" type="orm:many-to-one"
minOccurs="0" maxOccurs="unbounded"/> minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="one-to-many" type="orm:one-to-many" <xsd:element name="one-to-many" type="orm:one-to-many"
@ -799,6 +799,7 @@
<xsd:attribute name="precision" type="xsd:int"/> <xsd:attribute name="precision" type="xsd:int"/>
<xsd:attribute name="scale" type="xsd:int"/> <xsd:attribute name="scale" type="xsd:int"/>
<xsd:attribute name="comment" type="xsd:string"/> <xsd:attribute name="comment" type="xsd:string"/>
<xsd:attribute name="second-precision" type="xsd:int"/>
</xsd:complexType> </xsd:complexType>
<!-- **************************************************** --> <!-- **************************************************** -->

View File

@ -488,6 +488,16 @@ public class BootstrapTest {
return HibernatePersistenceProvider.class.getName(); return HibernatePersistenceProvider.class.getName();
} }
@Override
public String getScopeAnnotationName() {
return null;
}
@Override
public List<String> getQualifierAnnotationNames() {
return List.of();
}
@Override @Override
public PersistenceUnitTransactionType getTransactionType() { public PersistenceUnitTransactionType getTransactionType() {
return transactionType; return transactionType;

View File

@ -48,7 +48,7 @@ public class HbmNamedQueryConfigurationTest {
NamedObjectRepository namedObjectRepository = scope.getSessionFactory() NamedObjectRepository namedObjectRepository = scope.getSessionFactory()
.getQueryEngine() .getQueryEngine()
.getNamedObjectRepository(); .getNamedObjectRepository();
NamedSqmQueryMemento sqmQueryMemento = namedObjectRepository.getSqmQueryMemento( Bar.FIND_ALL ); NamedSqmQueryMemento<?> sqmQueryMemento = namedObjectRepository.getSqmQueryMemento( Bar.FIND_ALL );
assertTrue( sqmQueryMemento.getCacheable() ); assertTrue( sqmQueryMemento.getCacheable() );
} }

View File

@ -31,7 +31,7 @@ public class XmlCacheableNamedQueryTests {
void testCacheableQueryOverride(SessionFactoryScope scope) { void testCacheableQueryOverride(SessionFactoryScope scope) {
final SessionFactoryImplementor sessionFactory = scope.getSessionFactory(); final SessionFactoryImplementor sessionFactory = scope.getSessionFactory();
final NamedObjectRepository namedObjectRepository = sessionFactory.getQueryEngine().getNamedObjectRepository(); final NamedObjectRepository namedObjectRepository = sessionFactory.getQueryEngine().getNamedObjectRepository();
final NamedSqmQueryMemento queryMemento = namedObjectRepository.getSqmQueryMemento( SimpleEntity.FIND_ALL ); final NamedSqmQueryMemento<?> queryMemento = namedObjectRepository.getSqmQueryMemento( SimpleEntity.FIND_ALL );
assertThat( queryMemento ).isNotNull(); assertThat( queryMemento ).isNotNull();
assertThat( queryMemento.getCacheable() ).isNotNull(); assertThat( queryMemento.getCacheable() ).isNotNull();
assertThat( queryMemento.getCacheable() ).isTrue(); assertThat( queryMemento.getCacheable() ).isTrue();

View File

@ -146,6 +146,16 @@ public class JpaXsdVersionsTest {
return persistenceSchemaVersion; return persistenceSchemaVersion;
} }
@Override
public String getScopeAnnotationName() {
return null;
}
@Override
public List<String> getQualifierAnnotationNames() {
return List.of();
}
private final List<String> mappingFileNames = new ArrayList<String>(); private final List<String> mappingFileNames = new ArrayList<String>();
public List<String> getMappingFileNames() { public List<String> getMappingFileNames() {

View File

@ -108,7 +108,7 @@ public class AddNamedQueryTest {
// first, lets check the underlying stored query def // first, lets check the underlying stored query def
SessionFactoryImplementor sfi = scope.getEntityManagerFactory() SessionFactoryImplementor sfi = scope.getEntityManagerFactory()
.unwrap( SessionFactoryImplementor.class ); .unwrap( SessionFactoryImplementor.class );
NamedSqmQueryMemento def = sfi.getQueryEngine() NamedSqmQueryMemento<?> def = sfi.getQueryEngine()
.getNamedObjectRepository() .getNamedObjectRepository()
.getSqmQueryMemento( name ); .getSqmQueryMemento( name );
assertEquals( LockMode.OPTIMISTIC, def.getLockOptions().getLockMode() ); assertEquals( LockMode.OPTIMISTIC, def.getLockOptions().getLockMode() );
@ -139,7 +139,7 @@ public class AddNamedQueryTest {
// first, lets check the underlying stored query def // first, lets check the underlying stored query def
SessionFactoryImplementor sfi = scope.getEntityManagerFactory() SessionFactoryImplementor sfi = scope.getEntityManagerFactory()
.unwrap( SessionFactoryImplementor.class ); .unwrap( SessionFactoryImplementor.class );
NamedSqmQueryMemento def = sfi.getQueryEngine() NamedSqmQueryMemento<?> def = sfi.getQueryEngine()
.getNamedObjectRepository() .getNamedObjectRepository()
.getSqmQueryMemento( name ); .getSqmQueryMemento( name );
assertEquals( FlushMode.COMMIT, def.getFlushMode() ); assertEquals( FlushMode.COMMIT, def.getFlushMode() );

View File

@ -35,10 +35,10 @@ public class SimpleNamedQueryTests {
.getQueryEngine() .getQueryEngine()
.getNamedObjectRepository(); .getNamedObjectRepository();
final NamedSqmQueryMemento simpleMemento = namedObjectRepository.getSqmQueryMemento( "simple" ); final NamedSqmQueryMemento<?> simpleMemento = namedObjectRepository.getSqmQueryMemento( "simple" );
assertThat( simpleMemento, notNullValue() ); assertThat( simpleMemento, notNullValue() );
final NamedSqmQueryMemento restrictedMemento = namedObjectRepository.getSqmQueryMemento( "restricted" ); final NamedSqmQueryMemento<?> restrictedMemento = namedObjectRepository.getSqmQueryMemento( "restricted" );
assertThat( restrictedMemento, notNullValue() ); assertThat( restrictedMemento, notNullValue() );
} }
@ -54,10 +54,10 @@ public class SimpleNamedQueryTests {
.getQueryEngine() .getQueryEngine()
.getNamedObjectRepository(); .getNamedObjectRepository();
final NamedSqmQueryMemento simpleMemento = namedObjectRepository.getSqmQueryMemento( "simple" ); final NamedSqmQueryMemento<?> simpleMemento = namedObjectRepository.getSqmQueryMemento( "simple" );
assertThat( simpleMemento, notNullValue() ); assertThat( simpleMemento, notNullValue() );
final NamedSqmQueryMemento restrictedMemento = namedObjectRepository.getSqmQueryMemento( "restricted" ); final NamedSqmQueryMemento<?> restrictedMemento = namedObjectRepository.getSqmQueryMemento( "restricted" );
assertThat( restrictedMemento, notNullValue() ); assertThat( restrictedMemento, notNullValue() );
} }

View File

@ -40,7 +40,7 @@ dependencies {
api jakartaLibs.jpa api jakartaLibs.jpa
api jakartaLibs.jta api jakartaLibs.jta
runtime libs.antlr runtime libs.antlrRuntime
runtime libs.logging runtime libs.logging
runtime libs.byteBuddy runtime libs.byteBuddy
runtime libs.byteBuddyAgent runtime libs.byteBuddyAgent

View File

@ -40,6 +40,16 @@ public class PersistenceUnitInfoAdapter implements PersistenceUnitInfo {
return HibernatePersistenceProvider.class.getName(); return HibernatePersistenceProvider.class.getName();
} }
@Override
public String getScopeAnnotationName() {
return null;
}
@Override
public List<String> getQualifierAnnotationNames() {
return List.of();
}
public PersistenceUnitTransactionType getTransactionType() { public PersistenceUnitTransactionType getTransactionType() {
return null; return null;
} }

View File

@ -31,8 +31,11 @@ import org.hibernate.jpa.HibernatePersistenceProvider;
*/ */
public class PersistenceUnitInfoImpl implements PersistenceUnitInfo { public class PersistenceUnitInfoImpl implements PersistenceUnitInfo {
private final String name; private final String name;
private final Properties properties = new Properties(); private final Properties properties = new Properties();
private String scopeAnnotationName;
private List<String> qualifierAnnotationNames = List.of();
private PersistenceUnitTransactionType transactionType; private PersistenceUnitTransactionType transactionType;
private SharedCacheMode cacheMode; private SharedCacheMode cacheMode;
private ValidationMode validationMode; private ValidationMode validationMode;
@ -50,6 +53,24 @@ public class PersistenceUnitInfoImpl implements PersistenceUnitInfo {
return name; return name;
} }
@Override
public String getScopeAnnotationName() {
return scopeAnnotationName;
}
public void setScopeAnnotationName(String scopeAnnotationName) {
this.scopeAnnotationName = scopeAnnotationName;
}
@Override
public List<String> getQualifierAnnotationNames() {
return qualifierAnnotationNames;
}
public void setQualifierAnnotationNames(List<String> qualifierAnnotationNames) {
this.qualifierAnnotationNames = qualifierAnnotationNames;
}
@Override @Override
public Properties getProperties() { public Properties getProperties() {
return properties; return properties;

View File

@ -33,6 +33,16 @@ public class DelegatingPersistenceUnitInfo implements PersistenceUnitInfo {
return delegate.getPersistenceProviderClassName(); return delegate.getPersistenceProviderClassName();
} }
@Override
public String getScopeAnnotationName() {
return delegate.getScopeAnnotationName();
}
@Override
public List<String> getQualifierAnnotationNames() {
return delegate.getQualifierAnnotationNames();
}
@Override @Override
public PersistenceUnitTransactionType getTransactionType() { public PersistenceUnitTransactionType getTransactionType() {
return delegate.getTransactionType(); return delegate.getTransactionType();

View File

@ -40,6 +40,16 @@ public class PersistenceUnitInfoAdapter implements PersistenceUnitInfo {
return HibernatePersistenceProvider.class.getName(); return HibernatePersistenceProvider.class.getName();
} }
@Override
public String getScopeAnnotationName() {
return null;
}
@Override
public List<String> getQualifierAnnotationNames() {
return List.of();
}
@Override @Override
public PersistenceUnitTransactionType getTransactionType() { public PersistenceUnitTransactionType getTransactionType() {
return PersistenceUnitTransactionType.RESOURCE_LOCAL; return PersistenceUnitTransactionType.RESOURCE_LOCAL;

View File

@ -66,6 +66,16 @@ public class PersistenceUnitInfoPropertiesWrapper implements PersistenceUnitInfo
return HibernatePersistenceProvider.class.getName(); return HibernatePersistenceProvider.class.getName();
} }
@Override
public String getScopeAnnotationName() {
return null;
}
@Override
public List<String> getQualifierAnnotationNames() {
return List.of();
}
public PersistenceUnitTransactionType getTransactionType() { public PersistenceUnitTransactionType getTransactionType() {
return null; return null;
} }