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 @Nullable Cache getCache();
}
public interface EntityTransaction {
@Nullable Integer getTimeout();
}
public interface Parameter {
public @Nullable String getName();
public @Nullable Integer getPosition();

View File

@ -349,6 +349,31 @@ public final class Hibernate {
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
* 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.LockModeType;
import jakarta.persistence.PessimisticLockScope;
import jakarta.persistence.TypedQueryReference;
import jakarta.persistence.criteria.CriteriaDelete;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.CriteriaUpdate;
@ -1574,6 +1575,9 @@ public interface Session extends SharedSessionContract, EntityManager {
@Override
<R> Query<R> createQuery(String queryString, Class<R> resultClass);
@Override
<R> Query<R> createQuery(TypedQueryReference<R> typedQueryReference);
@Override @Deprecated @SuppressWarnings("rawtypes")
Query createQuery(String queryString);

View File

@ -8,6 +8,7 @@ package org.hibernate;
import jakarta.persistence.EntityTransaction;
import jakarta.transaction.Synchronization;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.hibernate.resource.transaction.spi.TransactionStatus;
@ -66,7 +67,7 @@ public interface Transaction extends EntityTransaction {
*
* @return The timeout, in seconds.
*/
int getTimeout();
@Nullable Integer getTimeout();
/**
* 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.CacheStoreMode;
import jakarta.persistence.EntityManager;
import org.hibernate.Remove;
import static java.lang.annotation.ElementType.PACKAGE;
@ -47,6 +49,15 @@ public @interface NamedQuery {
*/
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.
*

View File

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

View File

@ -164,8 +164,8 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector,
private Database database;
private final Map<String, NamedHqlQueryDefinition> namedQueryMap = new HashMap<>();
private final Map<String, NamedNativeQueryDefinition> namedNativeQueryMap = new HashMap<>();
private final Map<String, NamedHqlQueryDefinition<?>> namedQueryMap = new HashMap<>();
private final Map<String, NamedNativeQueryDefinition<?>> namedNativeQueryMap = new HashMap<>();
private final Map<String, NamedProcedureCallDefinition> namedProcedureCallMap = new HashMap<>();
private final Map<String, NamedResultSetMappingDescriptor> sqlResultSetMappingMap = new HashMap<>();
@ -763,7 +763,7 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector,
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Named query handling
public NamedHqlQueryDefinition getNamedHqlQueryMapping(String name) {
public NamedHqlQueryDefinition<?> getNamedHqlQueryMapping(String name) {
if ( name == null ) {
throw new IllegalArgumentException( "null is not a valid query name" );
}
@ -771,12 +771,12 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector,
}
@Override
public void visitNamedHqlQueryDefinitions(Consumer<NamedHqlQueryDefinition> definitionConsumer) {
public void visitNamedHqlQueryDefinitions(Consumer<NamedHqlQueryDefinition<?>> definitionConsumer) {
namedQueryMap.values().forEach( definitionConsumer );
}
@Override
public void addNamedQuery(NamedHqlQueryDefinition def) {
public void addNamedQuery(NamedHqlQueryDefinition<?> def) {
if ( def == null ) {
throw new IllegalArgumentException( "Named query definition is null" );
}
@ -791,7 +791,7 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector,
applyNamedQuery( def.getRegistrationName(), def );
}
private void applyNamedQuery(String name, NamedHqlQueryDefinition query) {
private void applyNamedQuery(String name, NamedHqlQueryDefinition<?> query) {
checkQueryName( name );
namedQueryMap.put( name.intern(), query );
}
@ -803,7 +803,7 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector,
}
@Override
public void addDefaultQuery(NamedHqlQueryDefinition queryDefinition) {
public void addDefaultQuery(NamedHqlQueryDefinition<?> queryDefinition) {
applyNamedQuery( queryDefinition.getRegistrationName(), queryDefinition );
defaultNamedQueryNames.add( queryDefinition.getRegistrationName() );
}
@ -812,17 +812,17 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector,
// Named native-query handling
@Override
public NamedNativeQueryDefinition getNamedNativeQueryMapping(String name) {
public NamedNativeQueryDefinition<?> getNamedNativeQueryMapping(String name) {
return namedNativeQueryMap.get( name );
}
@Override
public void visitNamedNativeQueryDefinitions(Consumer<NamedNativeQueryDefinition> definitionConsumer) {
public void visitNamedNativeQueryDefinitions(Consumer<NamedNativeQueryDefinition<?>> definitionConsumer) {
namedNativeQueryMap.values().forEach( definitionConsumer );
}
@Override
public void addNamedNativeQuery(NamedNativeQueryDefinition def) {
public void addNamedNativeQuery(NamedNativeQueryDefinition<?> def) {
if ( def == null ) {
throw new IllegalArgumentException( "Named native query definition object is null" );
}
@ -837,13 +837,13 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector,
applyNamedNativeQuery( def.getRegistrationName(), def );
}
private void applyNamedNativeQuery(String name, NamedNativeQueryDefinition query) {
private void applyNamedNativeQuery(String name, NamedNativeQueryDefinition<?> query) {
checkQueryName( name );
namedNativeQueryMap.put( name.intern(), query );
}
@Override
public void addDefaultNamedNativeQuery(NamedNativeQueryDefinition query) {
public void addDefaultNamedNativeQuery(NamedNativeQueryDefinition<?> query) {
applyNamedNativeQuery( query.getRegistrationName(), query );
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, String> imports;
private final Map<String, IdentifierGeneratorDefinition> idGeneratorDefinitionMap;
private final Map<String, NamedHqlQueryDefinition> namedQueryMap;
private final Map<String, NamedNativeQueryDefinition> namedNativeQueryMap;
private final Map<String, NamedHqlQueryDefinition<?>> namedQueryMap;
private final Map<String, NamedNativeQueryDefinition<?>> namedNativeQueryMap;
private final Map<String, NamedProcedureCallDefinition> namedProcedureCallMap;
private final Map<String, NamedResultSetMappingDescriptor> sqlResultSetMappingMap;
private final Map<String, NamedEntityGraphDefinition> namedEntityGraphMap;
@ -123,8 +123,8 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
Map<String, FetchProfile> fetchProfileMap,
Map<String, String> imports,
Map<String, IdentifierGeneratorDefinition> idGeneratorDefinitionMap,
Map<String, NamedHqlQueryDefinition> namedQueryMap,
Map<String, NamedNativeQueryDefinition> namedNativeQueryMap,
Map<String, NamedHqlQueryDefinition<?>> namedQueryMap,
Map<String, NamedNativeQueryDefinition<?>> namedNativeQueryMap,
Map<String, NamedProcedureCallDefinition> namedProcedureCallMap,
Map<String, NamedResultSetMappingDescriptor> sqlResultSetMappingMap,
Map<String, NamedEntityGraphDefinition> namedEntityGraphMap,
@ -246,22 +246,22 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
}
@Override
public NamedHqlQueryDefinition getNamedHqlQueryMapping(String name) {
public NamedHqlQueryDefinition<?> getNamedHqlQueryMapping(String name) {
return namedQueryMap.get( name );
}
@Override
public void visitNamedHqlQueryDefinitions(Consumer<NamedHqlQueryDefinition> definitionConsumer) {
public void visitNamedHqlQueryDefinitions(Consumer<NamedHqlQueryDefinition<?>> definitionConsumer) {
namedQueryMap.values().forEach( definitionConsumer );
}
@Override
public NamedNativeQueryDefinition getNamedNativeQueryMapping(String name) {
public NamedNativeQueryDefinition<?> getNamedNativeQueryMapping(String name) {
return namedNativeQueryMap.get( name );
}
@Override
public void visitNamedNativeQueryDefinitions(Consumer<NamedNativeQueryDefinition> definitionConsumer) {
public void visitNamedNativeQueryDefinitions(Consumer<NamedNativeQueryDefinition<?>> definitionConsumer) {
namedNativeQueryMap.values().forEach( definitionConsumer );
}
@ -370,16 +370,16 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
);
}
private Map<String, NamedSqmQueryMemento> buildNamedSqmMementos(SessionFactoryImplementor sessionFactory) {
final HashMap<String, NamedSqmQueryMemento> map = new HashMap<>();
private Map<String, NamedSqmQueryMemento<?>> buildNamedSqmMementos(SessionFactoryImplementor sessionFactory) {
final HashMap<String, NamedSqmQueryMemento<?>> map = new HashMap<>();
if ( namedQueryMap != null ) {
namedQueryMap.forEach( (key, value) -> map.put( key, value.resolve( sessionFactory ) ) );
}
return map;
}
private Map<String, NamedNativeQueryMemento> buildNamedNativeMementos(SessionFactoryImplementor sessionFactory) {
final HashMap<String, NamedNativeQueryMemento> map = new HashMap<>();
private Map<String, NamedNativeQueryMemento<?>> buildNamedNativeMementos(SessionFactoryImplementor sessionFactory) {
final HashMap<String, NamedNativeQueryMemento<?>> map = new HashMap<>();
if ( namedNativeQueryMap != null ) {
namedNativeQueryMap.forEach( (key, value) -> map.put( key, value.resolve( sessionFactory ) ) );
}
@ -652,11 +652,11 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
return bootstrapContext;
}
public Map<String, NamedHqlQueryDefinition> getNamedQueryMap() {
public Map<String, NamedHqlQueryDefinition<?>> getNamedQueryMap() {
return namedQueryMap;
}
public Map<String, NamedNativeQueryDefinition> getNamedNativeQueryMap() {
public Map<String, NamedNativeQueryDefinition<?>> getNamedNativeQueryMap() {
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.sqm.spi.NamedSqmQueryMemento;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* @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 Integer firstResult;
private final Integer maxResults;
@ -28,6 +30,7 @@ public class NamedHqlQueryDefinitionImpl extends AbstractNamedQueryDefinition im
public NamedHqlQueryDefinitionImpl(
String name,
@Nullable Class<E> resultType,
String hqlString,
Integer firstResult,
Integer maxResults,
@ -44,6 +47,7 @@ public class NamedHqlQueryDefinitionImpl extends AbstractNamedQueryDefinition im
Map<String,Object> hints) {
super(
name,
resultType,
cacheable,
cacheRegion,
cacheMode,
@ -67,9 +71,10 @@ public class NamedHqlQueryDefinitionImpl extends AbstractNamedQueryDefinition im
}
@Override
public NamedSqmQueryMemento resolve(SessionFactoryImplementor factory) {
return new NamedHqlQueryMementoImpl(
public NamedSqmQueryMemento<E> resolve(SessionFactoryImplementor factory) {
return new NamedHqlQueryMementoImpl<>(
getRegistrationName(),
getResultType(),
hqlString,
firstResult,
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.spi.NamedNativeQueryMemento;
import org.checkerframework.checker.nullness.qual.Nullable;
import static org.hibernate.internal.util.StringHelper.isNotEmpty;
/**
* @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 resultSetMappingName;
private final String resultSetMappingClassName;
private final Set<String> querySpaces;
private final Integer firstResult;
private final Integer maxResults;
public NamedNativeQueryDefinitionImpl(
String name,
@Nullable Class<E> resultType,
String sqlString,
String resultSetMappingName,
String resultSetMappingClassName,
Set<String> querySpaces,
Boolean cacheable,
String cacheRegion,
@ -50,6 +51,7 @@ public class NamedNativeQueryDefinitionImpl extends AbstractNamedQueryDefinition
Map<String,Object> hints) {
super(
name,
resultType,
cacheable,
cacheRegion,
cacheMode,
@ -63,7 +65,6 @@ public class NamedNativeQueryDefinitionImpl extends AbstractNamedQueryDefinition
);
this.sqlString = sqlString;
this.resultSetMappingName = resultSetMappingName;
this.resultSetMappingClassName = resultSetMappingClassName;
this.querySpaces = querySpaces;
this.firstResult = firstResult;
this.maxResults = maxResults;
@ -80,21 +81,13 @@ public class NamedNativeQueryDefinitionImpl extends AbstractNamedQueryDefinition
}
@Override
public String getResultSetMappingClassName() {
return resultSetMappingClassName;
}
@Override
public NamedNativeQueryMemento resolve(SessionFactoryImplementor factory) {
return new NamedNativeQueryMementoImpl(
public NamedNativeQueryMemento<E> resolve(SessionFactoryImplementor factory) {
return new NamedNativeQueryMementoImpl<>(
getRegistrationName(),
getResultType(),
sqlString,
sqlString,
resultSetMappingName,
isNotEmpty( resultSetMappingClassName )
? factory.getServiceRegistry().requireService( ClassLoaderService.class )
.classForName( resultSetMappingClassName )
: null,
querySpaces,
getCacheable(),
getCacheRegion(),

View File

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

View File

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

View File

@ -7,6 +7,7 @@
package org.hibernate.boot.jaxb.mapping.spi;
import jakarta.persistence.AccessType;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Common interface for JAXB bindings representing entities, mapped-superclasses and embeddables (JPA collective
@ -17,21 +18,21 @@ import jakarta.persistence.AccessType;
*/
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() {
return null;
}
default Integer getSecondPrecision() {
return null;
}
}

View File

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

View File

@ -784,6 +784,11 @@ public class AnnotatedColumn {
}
else {
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.handleArrayLength( inferredData );

View File

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

View File

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

View File

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

View File

@ -6,12 +6,19 @@
*/
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.JaxbAssociationOverrideImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbAttributeOverrideImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbAttributesContainer;
import org.hibernate.boot.jaxb.mapping.spi.JaxbBaseAttributesContainer;
import org.hibernate.boot.jaxb.mapping.spi.JaxbBasicImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbElementCollectionImpl;
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.JaxbManyToOneImpl;
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.JaxbPersistentAttribute;
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.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.EmbeddedAttributeProcessing;
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.OneToOneAttributeProcessing;
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.models.spi.MutableAnnotationUsage;
import org.hibernate.models.spi.MutableClassDetails;
import org.hibernate.models.spi.MutableMemberDetails;
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
@ -208,5 +227,100 @@ public class AttributeProcessor {
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.JaxbManagedType;
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.JaxbTenantIdImpl;
import org.hibernate.boot.models.HibernateAnnotations;
@ -154,47 +153,35 @@ public class ManagedTypeProcessor {
if ( jaxbManagedType instanceof JaxbEntityImpl jaxbDynamicEntity ) {
final JaxbAttributesContainerImpl attributes = jaxbDynamicEntity.getAttributes();
if ( CollectionHelper.isNotEmpty( attributes.getIdAttributes() ) ) {
// <id/>
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(
embeddedId.getName(),
attributeJavaType,
classDetails,
MEMBER_MODIFIERS,
false,
false,
xmlDocumentContext.getModelBuildingContext()
);
classDetails.addField( member );
}
// <natural-id/>
if ( attributes.getNaturalId() != null ) {
attributes.getNaturalId().getBasicAttributes().forEach( (jaxbBasic) -> {
if ( attributes != null ) {
if ( CollectionHelper.isNotEmpty( attributes.getIdAttributes() ) ) {
// <id/>
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(
jaxbBasic,
embeddedId,
xmlDocumentContext
);
final DynamicFieldDetails member = new DynamicFieldDetails(
jaxbBasic.getName(),
embeddedId.getName(),
attributeJavaType,
classDetails,
MEMBER_MODIFIERS,
@ -203,52 +190,78 @@ public class ManagedTypeProcessor {
xmlDocumentContext.getModelBuildingContext()
);
classDetails.addField( member );
} );
}
attributes.getNaturalId().getEmbeddedAttributes().forEach( (jaxbEmbedded) -> {
final TypeDetails attributeJavaType = determineDynamicAttributeJavaType(
jaxbEmbedded,
xmlDocumentContext
);
final DynamicFieldDetails member = new DynamicFieldDetails(
jaxbEmbedded.getName(),
attributeJavaType,
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(
jaxbBasic,
xmlDocumentContext
);
final DynamicFieldDetails member = new DynamicFieldDetails(
jaxbBasic.getName(),
attributeJavaType,
classDetails,
MEMBER_MODIFIERS,
false,
false,
xmlDocumentContext.getModelBuildingContext()
);
classDetails.addField( member );
} );
attributes.getNaturalId().getManyToOneAttributes().forEach( (jaxbManyToOne) -> {
final TypeDetails attributeJavaType = determineDynamicAttributeJavaType( jaxbManyToOne, xmlDocumentContext );
final DynamicFieldDetails member = new DynamicFieldDetails(
jaxbManyToOne.getName(),
attributeJavaType,
classDetails,
MEMBER_MODIFIERS,
false,
false,
xmlDocumentContext.getModelBuildingContext()
);
classDetails.addField( member );
} );
attributes.getNaturalId().getEmbeddedAttributes().forEach( (jaxbEmbedded) -> {
final TypeDetails attributeJavaType = determineDynamicAttributeJavaType(
jaxbEmbedded,
xmlDocumentContext
);
final DynamicFieldDetails member = new DynamicFieldDetails(
jaxbEmbedded.getName(),
attributeJavaType,
classDetails,
MEMBER_MODIFIERS,
false,
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 );
} );
attributes.getNaturalId().getManyToOneAttributes().forEach( (jaxbManyToOne) -> {
final TypeDetails attributeJavaType = determineDynamicAttributeJavaType(
jaxbManyToOne,
xmlDocumentContext
);
final DynamicFieldDetails member = new DynamicFieldDetails(
jaxbManyToOne.getName(),
attributeJavaType,
classDetails,
MEMBER_MODIFIERS,
false,
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>
@ -273,12 +286,35 @@ public class ManagedTypeProcessor {
else if ( jaxbManagedType instanceof JaxbMappedSuperclassImpl jaxbMappedSuperclass ) {
final JaxbAttributesContainerImpl attributes = jaxbMappedSuperclass.getAttributes();
if ( CollectionHelper.isNotEmpty( attributes.getIdAttributes() ) ) {
// <id/>
attributes.getIdAttributes().forEach( (jaxbId) -> {
final TypeDetails attributeJavaType = determineDynamicAttributeJavaType( jaxbId, xmlDocumentContext );
if ( attributes != null ) {
if ( CollectionHelper.isNotEmpty( attributes.getIdAttributes() ) ) {
// <id/>
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(
jaxbId.getName(),
embeddedId.getName(),
attributeJavaType,
classDetails,
MEMBER_MODIFIERS,
@ -287,15 +323,18 @@ public class ManagedTypeProcessor {
xmlDocumentContext.getModelBuildingContext()
);
classDetails.addField( member );
} );
}
}
else {
// <embedded-id/>
final JaxbEmbeddedIdImpl embeddedId = attributes.getEmbeddedIdAttribute();
final TypeDetails attributeJavaType = determineDynamicAttributeJavaType( embeddedId, xmlDocumentContext );
}
final JaxbAttributesContainer attributes = jaxbManagedType.getAttributes();
if ( attributes != null ) {
// <basic/>
attributes.getBasicAttributes().forEach( (jaxbBasic) -> {
final DynamicFieldDetails member = new DynamicFieldDetails(
embeddedId.getName(),
attributeJavaType,
jaxbBasic.getName(),
determineDynamicAttributeJavaType( jaxbBasic, xmlDocumentContext ),
classDetails,
MEMBER_MODIFIERS,
false,
@ -303,140 +342,124 @@ public class ManagedTypeProcessor {
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 );
} );
}
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(
@ -503,6 +526,16 @@ public class ManagedTypeProcessor {
xmlDocumentContext
);
}
AttributeProcessor.processAttributeOverrides(
jaxbEntity.getAttributeOverrides(),
classDetails,
xmlDocumentContext
);
AttributeProcessor.processAssociationOverrides(
jaxbEntity.getAssociationOverrides(),
classDetails,
xmlDocumentContext
);
QueryProcessing.applyNamedQueries( jaxbEntity, classDetails, xmlDocumentContext );
QueryProcessing.applyNamedNativeQueries( jaxbEntity, classDetails, jaxbRoot, xmlDocumentContext );
@ -779,17 +812,25 @@ public class ManagedTypeProcessor {
jaxbMappedSuperclass.getAccess(),
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();
processIdMappings(
attributes,
classAccessType,
classDetails,
ManagedTypeProcessor::adjustNonDynamicTypeMember,
xmlDocumentContext
);
AttributeProcessor.processAttributes( attributes, classDetails, classAccessType, xmlDocumentContext );
if ( attributes != null ) {
processIdMappings(
attributes,
classAccessType,
classDetails,
ManagedTypeProcessor::adjustNonDynamicTypeMember,
xmlDocumentContext
);
AttributeProcessor.processAttributes( attributes, classDetails, classAccessType, xmlDocumentContext );
}
processEntityOrMappedSuperclass( jaxbMappedSuperclass, classDetails, xmlDocumentContext );
}
@ -882,15 +923,22 @@ public class ManagedTypeProcessor {
AttributeProcessor.MemberAdjuster memberAdjuster,
XmlDocumentContext xmlDocumentContext) {
XmlProcessingHelper.getOrMakeAnnotation( Embeddable.class, classDetails, xmlDocumentContext );
classDetails.addAnnotationUsage( XmlAnnotationHelper.createAccessAnnotation( classAccessType, classDetails, xmlDocumentContext ) );
AttributeProcessor.processAttributes(
jaxbEmbeddable.getAttributes(),
classDetails,
AccessType.FIELD,
memberAdjuster,
xmlDocumentContext
);
if ( classAccessType != null ) {
classDetails.addAnnotationUsage( XmlAnnotationHelper.createAccessAnnotation(
classAccessType,
classDetails,
xmlDocumentContext
) );
}
if ( jaxbEmbeddable.getAttributes() != null ) {
AttributeProcessor.processAttributes(
jaxbEmbeddable.getAttributes(),
classDetails,
AccessType.FIELD,
memberAdjuster,
xmlDocumentContext
);
}
}
public static void processOverrideEmbeddable(List<XmlProcessingResult.OverrideTuple<JaxbEmbeddableImpl>> embeddableOverrides) {
@ -906,13 +954,15 @@ public class ManagedTypeProcessor {
XmlProcessingHelper.getOrMakeAnnotation( Embeddable.class, classDetails, xmlDocumentContext );
AttributeProcessor.processAttributes(
jaxbEmbeddable.getAttributes(),
classDetails,
AccessType.FIELD,
ManagedTypeProcessor::adjustNonDynamicTypeMember,
xmlDocumentContext
);
if ( jaxbEmbeddable.getAttributes() != null ) {
AttributeProcessor.processAttributes(
jaxbEmbeddable.getAttributes(),
classDetails,
AccessType.FIELD,
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.models.ModelsException;
import org.hibernate.models.spi.AnnotationDescriptor;
import org.hibernate.models.spi.AnnotationTarget;
import org.hibernate.models.spi.AnnotationUsage;
import org.hibernate.models.spi.ClassDetails;
import org.hibernate.models.spi.ClassDetailsRegistry;
@ -144,6 +145,7 @@ import jakarta.persistence.TableGenerator;
import jakarta.persistence.Temporal;
import jakarta.persistence.TemporalType;
import jakarta.persistence.UniqueConstraint;
import org.checkerframework.checker.nullness.qual.Nullable;
import static java.lang.Boolean.FALSE;
import static java.util.Collections.emptyList;
@ -420,7 +422,7 @@ public class XmlAnnotationHelper {
public static <A extends Annotation> void applyUniqueConstraints(
List<JaxbUniqueConstraintImpl> jaxbUniqueConstraints,
MutableAnnotationTarget target,
AnnotationTarget target,
MutableAnnotationUsage<A> annotationUsage,
XmlDocumentContext xmlDocumentContext) {
if ( CollectionHelper.isEmpty( jaxbUniqueConstraints ) ) {
@ -444,7 +446,7 @@ public class XmlAnnotationHelper {
public static <A extends Annotation> void applyIndexes(
List<JaxbIndexImpl> jaxbIndexes,
MutableAnnotationTarget target,
AnnotationTarget target,
MutableAnnotationUsage<A> annotationUsage,
XmlDocumentContext xmlDocumentContext) {
if ( CollectionHelper.isEmpty( jaxbIndexes ) ) {
@ -471,7 +473,7 @@ public class XmlAnnotationHelper {
public static <A extends Annotation> void applyCheckConstraints(
JaxbCheckable jaxbCheckable,
MutableAnnotationTarget target,
AnnotationTarget target,
MutableAnnotationUsage<A> annotationUsage,
XmlDocumentContext xmlDocumentContext) {
if ( jaxbCheckable!= null && CollectionHelper.isNotEmpty( jaxbCheckable.getCheckConstraints() ) ) {
@ -480,7 +482,7 @@ public class XmlAnnotationHelper {
.getAnnotationDescriptorRegistry()
.getDescriptor( CheckConstraint.class );
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::getConstraint, "constraint", checkAnn, checkConstraintDescriptor );
applyOr( jaxbCheck, JaxbCheckConstraintImpl::getOptions, "options", checkAnn, checkConstraintDescriptor );
@ -959,7 +961,7 @@ public class XmlAnnotationHelper {
public static <A extends Annotation> void applyTableAttributes(
JaxbTableMapping jaxbTable,
MutableAnnotationTarget target,
AnnotationTarget target,
MutableAnnotationUsage<A> tableAnn,
AnnotationDescriptor<A> annotationDescriptor,
XmlDocumentContext xmlDocumentContext) {
@ -1498,7 +1500,7 @@ public class XmlAnnotationHelper {
}
public static void applyDiscriminatorFormula(
JaxbDiscriminatorFormulaImpl jaxbDiscriminatorFormula,
@Nullable JaxbDiscriminatorFormulaImpl jaxbDiscriminatorFormula,
MutableClassDetails target,
XmlDocumentContext xmlDocumentContext) {
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.internal.util.StringHelper;
import org.hibernate.models.internal.dynamic.DynamicAnnotationUsage;
import org.hibernate.models.spi.AnnotationTarget;
import org.hibernate.models.spi.AnnotationUsage;
import org.hibernate.models.spi.FieldDetails;
import org.hibernate.models.spi.MethodDetails;
@ -139,7 +140,7 @@ public class XmlProcessingHelper {
*/
public static <A extends Annotation> MutableAnnotationUsage<A> makeNestedAnnotation(
Class<A> annotationType,
MutableAnnotationTarget target,
AnnotationTarget target,
XmlDocumentContext xmlDocumentContext) {
return new DynamicAnnotationUsage<>(
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.JaxbSingularFetchModeImpl;
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.spi.XmlDocumentContext;
import org.hibernate.models.spi.ClassDetails;
import org.hibernate.models.spi.MutableAnnotationUsage;
import org.hibernate.models.spi.MutableClassDetails;
import org.hibernate.models.spi.MutableMemberDetails;
import jakarta.persistence.Access;
import jakarta.persistence.AccessType;
import jakarta.persistence.FetchType;
import jakarta.persistence.Transient;
import static org.hibernate.internal.util.NullnessHelper.coalesce;
/**
* @author Steve Ebersole
@ -127,4 +132,17 @@ public class CommonAttributeProcessing {
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",
xmlDocumentContext.getModelBuildingContext()
.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.XmlProcessingHelper;
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.MutableAnnotationUsage;
import org.hibernate.models.spi.MutableMemberDetails;
@ -36,7 +37,7 @@ public class ColumnProcessing {
public static <A extends Annotation> void applyColumnDetails(
JaxbColumnCommon jaxbColumn,
MutableAnnotationTarget target,
AnnotationTarget target,
MutableAnnotationUsage<A> columnAnn,
XmlDocumentContext xmlDocumentContext) {
if ( jaxbColumn == null ) {
@ -98,7 +99,7 @@ public class ColumnProcessing {
public static <A extends Annotation> void applyColumnDetails(
JaxbColumn jaxbColumn,
MutableAnnotationTarget target,
AnnotationTarget target,
MutableAnnotationUsage<A> columnAnn,
XmlDocumentContext xmlDocumentContext) {
if ( jaxbColumn == null ) {
@ -170,6 +171,8 @@ public class ColumnProcessing {
XmlProcessingHelper.applyAttributeIfSpecified( "precision", jaxbColumn.getPrecision(), columnAnn );
XmlProcessingHelper.applyAttributeIfSpecified( "scale", jaxbColumn.getScale(), columnAnn );
XmlProcessingHelper.applyAttributeIfSpecified( "secondPrecision", jaxbColumn.getSecondPrecision(), columnAnn );
}
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.xml.internal.XmlAnnotationHelper;
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.MutableAnnotationUsage;
import org.hibernate.models.spi.MutableMemberDetails;
@ -53,12 +54,12 @@ public class ForeignKeyProcessing {
public static MutableAnnotationUsage<ForeignKey> createNestedForeignKeyAnnotation(
JaxbForeignKeyImpl jaxbForeignKey,
MemberDetails memberDetails,
AnnotationTarget annotationTarget,
XmlDocumentContext xmlDocumentContext) {
assert jaxbForeignKey != null;
final MutableAnnotationUsage<ForeignKey> foreignKeyUsage = JpaAnnotations.FOREIGN_KEY.createUsage(
memberDetails,
annotationTarget,
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.spi.XmlDocumentContext;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.models.spi.AnnotationTarget;
import org.hibernate.models.spi.AnnotationUsage;
import org.hibernate.models.spi.MutableAnnotationTarget;
import org.hibernate.models.spi.MutableAnnotationUsage;
import org.hibernate.models.spi.MutableMemberDetails;
@ -117,9 +119,9 @@ public class JoinColumnProcessing {
public static void transferJoinColumn(
JaxbColumnJoined jaxbJoinColumn,
MutableAnnotationUsage<? extends Annotation> joinColumnUsage,
MutableMemberDetails memberDetails,
AnnotationTarget annotationTarget,
XmlDocumentContext xmlDocumentContext) {
ColumnProcessing.applyColumnDetails( jaxbJoinColumn, memberDetails, joinColumnUsage, xmlDocumentContext );
ColumnProcessing.applyColumnDetails( jaxbJoinColumn, annotationTarget, joinColumnUsage, xmlDocumentContext );
XmlAnnotationHelper.applyOptionalAttribute(
joinColumnUsage,
"referencedColumnName",
@ -130,7 +132,7 @@ public class JoinColumnProcessing {
if ( jaxbForeignKey != null ) {
joinColumnUsage.setAttributeValue(
"foreignKey",
ForeignKeyProcessing.createNestedForeignKeyAnnotation( jaxbForeignKey, memberDetails, xmlDocumentContext )
ForeignKeyProcessing.createNestedForeignKeyAnnotation( jaxbForeignKey, annotationTarget, xmlDocumentContext )
);
}
}
@ -143,7 +145,7 @@ public class JoinColumnProcessing {
*/
public static List<AnnotationUsage<JoinColumn>> transformJoinColumnList(
List<JaxbJoinColumnImpl> jaxbJoinColumns,
MutableMemberDetails memberDetails,
AnnotationTarget annotationTarget,
XmlDocumentContext xmlDocumentContext) {
if ( CollectionHelper.isEmpty( jaxbJoinColumns ) ) {
return Collections.emptyList();
@ -151,7 +153,7 @@ public class JoinColumnProcessing {
final List<AnnotationUsage<JoinColumn>> joinColumns = new ArrayList<>( jaxbJoinColumns.size() );
jaxbJoinColumns.forEach( jaxbJoinColumn -> {
final MutableAnnotationUsage<JoinColumn> joinColumnAnn = JpaAnnotations.JOIN_COLUMN.createUsage(
memberDetails,
annotationTarget,
xmlDocumentContext.getModelBuildingContext()
);
transferJoinColumn( jaxbJoinColumn, joinColumnAnn, null, xmlDocumentContext );
@ -177,7 +179,7 @@ public class JoinColumnProcessing {
public static List<AnnotationUsage<JoinColumn>> createJoinColumns(
List<JaxbJoinColumnImpl> jaxbJoinColumns,
MutableMemberDetails memberDetails,
AnnotationTarget annotationTarget,
XmlDocumentContext xmlDocumentContext) {
if ( CollectionHelper.isEmpty( jaxbJoinColumns ) ) {
return Collections.emptyList();
@ -185,13 +187,13 @@ public class JoinColumnProcessing {
final List<AnnotationUsage<JoinColumn>> joinColumns = new ArrayList<>( jaxbJoinColumns.size() );
jaxbJoinColumns.forEach( jaxbJoinColumn -> {
final MutableAnnotationUsage<JoinColumn> joinColumnUsage = JpaAnnotations.JOIN_COLUMN.createUsage(
memberDetails,
annotationTarget,
xmlDocumentContext.getModelBuildingContext()
);
transferJoinColumn(
jaxbJoinColumn,
joinColumnUsage,
memberDetails,
annotationTarget,
xmlDocumentContext
);
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.models.JpaAnnotations;
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.internal.util.collections.CollectionHelper;
import org.hibernate.models.spi.AnnotationTarget;
import org.hibernate.models.spi.MutableAnnotationUsage;
import org.hibernate.models.spi.MutableMemberDetails;
import jakarta.persistence.AssociationOverride;
import jakarta.persistence.JoinTable;
/**
@ -35,15 +38,41 @@ public class TableProcessing {
JpaAnnotations.JOIN_TABLE,
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.applyTableAttributes( jaxbJoinTable, memberDetails, joinTableUsage, JpaAnnotations.JOIN_TABLE, xmlDocumentContext );
XmlAnnotationHelper.applyTableAttributes( jaxbJoinTable, annotationTarget, joinTableUsage, JpaAnnotations.JOIN_TABLE, xmlDocumentContext );
final List<JaxbJoinColumnImpl> joinColumns = jaxbJoinTable.getJoinColumn();
if ( CollectionHelper.isNotEmpty( joinColumns ) ) {
joinTableUsage.setAttributeValue( "joinColumns", JoinColumnProcessing.transformJoinColumnList(
joinColumns,
memberDetails,
annotationTarget,
xmlDocumentContext
) );
}
@ -51,7 +80,7 @@ public class TableProcessing {
if ( CollectionHelper.isNotEmpty( inverseJoinColumns ) ) {
joinTableUsage.setAttributeValue( "inverseJoinColumns", JoinColumnProcessing.transformJoinColumnList(
inverseJoinColumns,
memberDetails,
annotationTarget,
xmlDocumentContext
) );
}
@ -59,16 +88,14 @@ public class TableProcessing {
if ( jaxbJoinTable.getForeignKey() != null ) {
joinTableUsage.setAttributeValue(
"foreignKey",
ForeignKeyProcessing.createNestedForeignKeyAnnotation( jaxbJoinTable.getForeignKey(), memberDetails, xmlDocumentContext )
ForeignKeyProcessing.createNestedForeignKeyAnnotation( jaxbJoinTable.getForeignKey(), annotationTarget, xmlDocumentContext )
);
}
if ( jaxbJoinTable.getInverseForeignKey() != null ) {
joinTableUsage.setAttributeValue(
"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.LockOptions;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* @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 @Nullable Class<R> resultClass;
private Boolean cacheable;
private String cacheRegion;
@ -45,6 +48,11 @@ public abstract class AbstractNamedQueryBuilder<T extends AbstractNamedQueryBuil
protected abstract T getThis();
public T setResultClass(Class<R> resultClass) {
this.resultClass = resultClass;
return getThis();
}
public T setCacheable(Boolean cacheable) {
this.cacheable = cacheable;
return getThis();
@ -90,6 +98,10 @@ public abstract class AbstractNamedQueryBuilder<T extends AbstractNamedQueryBuil
return getThis();
}
public Class<R> getResultClass() {
return resultClass;
}
public Boolean getCacheable() {
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 Gavin King
*/
public interface NamedHqlQueryDefinition extends NamedQueryDefinition {
public interface NamedHqlQueryDefinition<E> extends NamedQueryDefinition<E> {
String getHqlString();
@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 Integer firstResult;
@ -42,7 +42,7 @@ public interface NamedHqlQueryDefinition extends NamedQueryDefinition {
}
@Override
protected Builder getThis() {
protected Builder<E> getThis() {
return this;
}
@ -50,24 +50,25 @@ public interface NamedHqlQueryDefinition extends NamedQueryDefinition {
return hqlString;
}
public Builder setHqlString(String hqlString) {
public Builder<E> setHqlString(String hqlString) {
this.hqlString = hqlString;
return this;
}
public Builder setFirstResult(Integer firstResult) {
public Builder<E> setFirstResult(Integer firstResult) {
this.firstResult = firstResult;
return getThis();
}
public Builder setMaxResults(Integer maxResults) {
public Builder<E> setMaxResults(Integer maxResults) {
this.maxResults = maxResults;
return getThis();
}
public NamedHqlQueryDefinitionImpl build() {
return new NamedHqlQueryDefinitionImpl(
public NamedHqlQueryDefinitionImpl<E> build() {
return new NamedHqlQueryDefinitionImpl<>(
getName(),
getResultClass(),
hqlString,
firstResult,
maxResults,

View File

@ -6,13 +6,13 @@
*/
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;
import org.hibernate.boot.spi.AbstractNamedQueryDefinition;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.query.sql.spi.NamedNativeQueryMemento;
@ -26,13 +26,110 @@ import org.hibernate.query.sql.spi.NamedNativeQueryMemento;
* @author Steve Ebersole
* @author Gavin King
*/
public interface NamedNativeQueryDefinition extends NamedQueryDefinition {
public interface NamedNativeQueryDefinition<E> extends NamedQueryDefinition<E> {
String getSqlQueryString();
String getResultSetMappingName();
String getResultSetMappingClassName();
@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
*/
public interface NamedProcedureCallDefinition extends NamedQueryDefinition {
public interface NamedProcedureCallDefinition extends NamedQueryDefinition<Object> {
/**
* The name of the underlying database procedure or function name
*/
String getProcedureName();
@Override
default Class<Object> getResultType() {
return Object.class;
}
@Override
NamedCallableQueryMemento resolve(SessionFactoryImplementor factory);
}

View File

@ -9,6 +9,8 @@ package org.hibernate.boot.query;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.query.named.NamedQueryMemento;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Common attributes shared across the mapping of named HQL, native
* 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 Gavin King
*/
public interface NamedQueryDefinition {
public interface NamedQueryDefinition<E> {
/**
* The name under which the query is to be registered
*/
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
*/
NamedQueryMemento resolve(SessionFactoryImplementor factory);
NamedQueryMemento<E> resolve(SessionFactoryImplementor factory);
}

View File

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

View File

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

View File

@ -180,12 +180,12 @@ public interface InFlightMetadataCollector extends MetadataImplementor {
*
* @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.
*/
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.
@ -318,9 +318,9 @@ public interface InFlightMetadataCollector extends MetadataImplementor {
void addDefaultIdentifierGenerator(IdentifierGeneratorDefinition generatorDefinition);
void addDefaultQuery(NamedHqlQueryDefinition queryDefinition);
void addDefaultQuery(NamedHqlQueryDefinition<?> queryDefinition);
void addDefaultNamedNativeQuery(NamedNativeQueryDefinition query);
void addDefaultNamedNativeQuery(NamedNativeQueryDefinition<?> query);
void addDefaultResultSetMapping(NamedResultSetMappingDescriptor definition);

View File

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

View File

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

View File

@ -21,6 +21,7 @@ import jakarta.persistence.PersistenceUnitTransactionType;
import jakarta.persistence.PersistenceUnitUtil;
import jakarta.persistence.Query;
import jakarta.persistence.SynchronizationType;
import jakarta.persistence.TypedQueryReference;
import org.hibernate.CustomEntityDirtinessStrategy;
import org.hibernate.HibernateException;
@ -234,6 +235,16 @@ public class SessionFactoryDelegatingImpl implements SessionFactoryImplementor,
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
public String bestGuessEntityName(Object object) {
return delegate.bestGuessEntityName( object );

View File

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

View File

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

View File

@ -7,6 +7,7 @@
package org.hibernate.engine.transaction.internal;
import jakarta.transaction.Synchronization;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.hibernate.HibernateException;
import org.hibernate.TransactionException;
@ -187,8 +188,17 @@ public class TransactionImpl implements TransactionImplementor {
}
@Override
public int getTimeout() {
return this.transactionCoordinator.getTimeOut();
public void setTimeout(@Nullable Integer seconds) {
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

View File

@ -111,6 +111,7 @@ import jakarta.persistence.FlushModeType;
import jakarta.persistence.NamedNativeQuery;
import jakarta.persistence.TransactionRequiredException;
import jakarta.persistence.Tuple;
import jakarta.persistence.TypedQueryReference;
import jakarta.persistence.criteria.CriteriaDelete;
import jakarta.persistence.criteria.CriteriaQuery;
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
@Override @SuppressWarnings("rawtypes")

View File

@ -132,6 +132,7 @@ import jakarta.persistence.PersistenceUnitTransactionType;
import jakarta.persistence.PersistenceUnitUtil;
import jakarta.persistence.Query;
import jakarta.persistence.SynchronizationType;
import jakarta.persistence.TypedQueryReference;
import static jakarta.persistence.SynchronizationType.SYNCHRONIZED;
import static java.util.Collections.emptySet;
@ -1081,6 +1082,16 @@ public class SessionFactoryImpl extends QueryParameterBindingTypeResolverImpl im
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
public void runInTransaction(Consumer<EntityManager> work) {
//noinspection unchecked,rawtypes

View File

@ -69,14 +69,12 @@ public class PersistenceUnitUtilImpl implements PersistenceUnitUtil, Serializabl
@Override
public void load(Object entity, String attributeName) {
// todo (jpa 3.2) : implement this
throw new UnsupportedOperationException( "Not yet implemented" );
Hibernate.initializeProperty( entity, attributeName );
}
@Override
public <E> void load(E entity, Attribute<? super E, ?> attribute) {
// todo (jpa 3.2) : implement this
throw new UnsupportedOperationException( "Not yet implemented" );
load( entity, attribute.getName() );
}
@Override
@ -86,14 +84,12 @@ public class PersistenceUnitUtilImpl implements PersistenceUnitUtil, Serializabl
@Override
public boolean isInstance(Object entity, Class<?> entityClass) {
// todo (jpa 3.2) : implement this
throw new UnsupportedOperationException( "Not yet implemented" );
return entityClass.isAssignableFrom( Hibernate.getClassLazy( entity ) );
}
@Override
public <T> Class<? extends T> getClass(T entity) {
// todo (jpa 3.2) : implement this
throw new UnsupportedOperationException( "Not yet implemented" );
return Hibernate.getClassLazy( entity );
}
@Override
@ -129,8 +125,26 @@ public class PersistenceUnitUtilImpl implements PersistenceUnitUtil, Serializabl
@Override
public Object getVersion(Object entity) {
// todo (jpa 3.2) : implement this
throw new UnsupportedOperationException( "Not yet implemented" );
if ( entity == null ) {
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) {
@ -150,4 +164,21 @@ public class PersistenceUnitUtilImpl implements PersistenceUnitUtil, Serializabl
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 {
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.namedQueryMemento = namedQueryMemento;
}

View File

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

View File

@ -7,7 +7,10 @@
package org.hibernate.metamodel.model.domain;
import java.util.List;
import java.util.Map;
import java.util.Set;
import jakarta.persistence.EntityGraph;
import jakarta.persistence.metamodel.EmbeddableType;
import jakarta.persistence.metamodel.EntityType;
import jakarta.persistence.metamodel.ManagedType;
@ -131,5 +134,7 @@ public interface JpaMetamodel extends Metamodel {
<T> List<RootGraphImplementor<? super T>> findEntityGraphsByJavaType(Class<T> entityClass);
<T> Map<String, EntityGraph<? extends T>> getNamedEntityGraphs(Class<T> entityType);
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
public String qualifyImportableName(String 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.spi.TypeConfiguration;
import jakarta.persistence.EntityGraph;
import jakarta.persistence.metamodel.EmbeddableType;
import jakarta.persistence.metamodel.EntityType;
import jakarta.persistence.metamodel.ManagedType;
@ -688,6 +689,11 @@ public class MappingMetamodelImpl extends QueryParameterBindingTypeResolverImpl
return jpaMetamodel.findEntityGraphByName( name );
}
@Override
public <T> Map<String, EntityGraph<? extends T>> getNamedEntityGraphs(Class<T> entityType) {
return jpaMetamodel.getNamedEntityGraphs( entityType );
}
@Override
public <T> List<RootGraphImplementor<? super T>> findEntityGraphsByJavaType(Class<T> entityClass) {
return jpaMetamodel.findEntityGraphsByJavaType( entityClass );

View File

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

View File

@ -861,8 +861,8 @@ public abstract class AbstractEntityPersister
}
}
private NamedQueryMemento getNamedQueryMemento(MetadataImplementor bootModel) {
final NamedQueryMemento memento =
private NamedQueryMemento<?> getNamedQueryMemento(MetadataImplementor bootModel) {
final NamedQueryMemento<?> memento =
factory.getQueryEngine().getNamedObjectRepository()
.resolve( factory, bootModel, queryLoaderName );
if ( memento == null ) {
@ -878,7 +878,7 @@ public abstract class AbstractEntityPersister
protected SingleIdEntityLoader<?> buildSingleIdEntityLoader() {
if ( hasNamedQueryLoader() ) {
// 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 buildSingleIdEntityLoader( new LoadQueryInfluencers( factory ) );

View File

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

View File

@ -22,7 +22,7 @@ import org.hibernate.query.named.NamedQueryMemento;
* @author Steve Ebersole
*/
@Incubating
public interface NamedCallableQueryMemento extends NamedQueryMemento {
public interface NamedCallableQueryMemento extends NamedQueryMemento<Object> {
/**
* 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 {
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.JpaCriteriaInsertSelect;
import jakarta.persistence.TypedQueryReference;
import jakarta.persistence.criteria.CriteriaDelete;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.CriteriaUpdate;
@ -105,6 +106,22 @@ public interface QueryProducer {
*/
<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}.
*/

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.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 maxResults;
@ -33,7 +36,8 @@ public class NamedCriteriaQueryMementoImpl extends AbstractNamedQueryMemento imp
public NamedCriteriaQueryMementoImpl(
String name,
SqmStatement sqmStatement,
@Nullable Class<E> resultType,
SqmStatement<E> sqmStatement,
Integer firstResult,
Integer maxResults,
Boolean cacheable,
@ -47,7 +51,7 @@ public class NamedCriteriaQueryMementoImpl extends AbstractNamedQueryMemento imp
String comment,
Map<String, String> parameterTypes,
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.firstResult = firstResult;
this.maxResults = maxResults;
@ -67,8 +71,8 @@ public class NamedCriteriaQueryMementoImpl extends AbstractNamedQueryMemento imp
}
@Override
public <T> SqmQueryImplementor<T> toQuery(SharedSessionContractImplementor session) {
return toQuery(session, null);
public SqmQueryImplementor<E> toQuery(SharedSessionContractImplementor session) {
return toQuery( session, getResultType() );
}
@Override
@ -86,7 +90,7 @@ public class NamedCriteriaQueryMementoImpl extends AbstractNamedQueryMemento imp
}
@Override
public SqmStatement<?> getSqmStatement() {
public SqmStatement<E> getSqmStatement() {
return sqmStatement;
}
@ -111,9 +115,10 @@ public class NamedCriteriaQueryMementoImpl extends AbstractNamedQueryMemento imp
}
@Override
public NamedSqmQueryMemento makeCopy(String name) {
return new NamedCriteriaQueryMementoImpl(
public NamedSqmQueryMemento<E> makeCopy(String name) {
return new NamedCriteriaQueryMementoImpl<E>(
name,
getResultType(),
sqmStatement,
firstResult,
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.tree.SqmStatement;
import org.jboss.logging.Logger;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Definition of a named query, defined in the mapping metadata.
* 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 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 Integer firstResult;
@ -41,6 +46,7 @@ public class NamedHqlQueryMementoImpl extends AbstractNamedQueryMemento implemen
public NamedHqlQueryMementoImpl(
String name,
@Nullable Class<R> resultType,
String hqlString,
Integer firstResult,
Integer maxResults,
@ -57,6 +63,7 @@ public class NamedHqlQueryMementoImpl extends AbstractNamedQueryMemento implemen
Map<String,Object> hints) {
super(
name,
resultType,
cacheable,
cacheRegion,
cacheMode,
@ -100,9 +107,10 @@ public class NamedHqlQueryMementoImpl extends AbstractNamedQueryMemento implemen
}
@Override
public NamedSqmQueryMemento makeCopy(String name) {
return new NamedHqlQueryMementoImpl(
public NamedSqmQueryMemento<R> makeCopy(String name) {
return new NamedHqlQueryMementoImpl<>(
name,
getResultType(),
hqlString,
firstResult,
maxResults,
@ -122,12 +130,12 @@ public class NamedHqlQueryMementoImpl extends AbstractNamedQueryMemento implemen
@Override
public void validate(QueryEngine queryEngine) {
queryEngine.getHqlTranslator().translate( hqlString, null );
queryEngine.getHqlTranslator().translate( hqlString, getResultType() );
}
@Override
public <T> SqmQueryImplementor<T> toQuery(SharedSessionContractImplementor session) {
return toQuery( session, null );
public SqmQueryImplementor<R> toQuery(SharedSessionContractImplementor session) {
return toQuery( session, getResultType() );
}
@Override
@ -140,7 +148,7 @@ public class NamedHqlQueryMementoImpl extends AbstractNamedQueryMemento implemen
}
@Override
public SqmStatement<?> getSqmStatement() {
public SqmStatement<R> getSqmStatement() {
return null;
}

View File

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

View File

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

View File

@ -6,20 +6,20 @@
*/
package org.hibernate.query.named;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.hibernate.CacheMode;
import org.hibernate.FlushMode;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* @author Steve Ebersole
* @author Gavin King
*/
public abstract class AbstractNamedQueryMemento implements NamedQueryMemento {
public abstract class AbstractNamedQueryMemento<R> implements NamedQueryMemento<R> {
private final String name;
private final @Nullable Class<R> resultType;
private final Boolean cacheable;
private final String cacheRegion;
@ -37,6 +37,7 @@ public abstract class AbstractNamedQueryMemento implements NamedQueryMemento {
protected AbstractNamedQueryMemento(
String name,
@Nullable Class<R> resultType,
Boolean cacheable,
String cacheRegion,
CacheMode cacheMode,
@ -47,6 +48,7 @@ public abstract class AbstractNamedQueryMemento implements NamedQueryMemento {
String comment,
Map<String, Object> hints) {
this.name = name;
this.resultType = resultType;
this.cacheable = cacheable;
this.cacheRegion = cacheRegion;
this.cacheMode = cacheMode;
@ -63,6 +65,11 @@ public abstract class AbstractNamedQueryMemento implements NamedQueryMemento {
return name;
}
@Override
public @Nullable Class<R> getResultType() {
return resultType;
}
@Override
public Boolean getCacheable() {
return cacheable;
@ -108,141 +115,4 @@ public abstract class AbstractNamedQueryMemento implements NamedQueryMemento {
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
*/
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.sqm.spi.NamedSqmQueryMemento;
import jakarta.persistence.TypedQueryReference;
/**
* Repository for references to named things related to queries. This includes:
* <ul>
@ -31,20 +33,22 @@ import org.hibernate.query.sqm.spi.NamedSqmQueryMemento;
@Incubating
public interface NamedObjectRepository {
<R> Map<String, TypedQueryReference<R>> getNamedQueries(Class<R> resultType);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Named SQM Memento
NamedSqmQueryMemento getSqmQueryMemento(String queryName);
void visitSqmQueryMementos(Consumer<NamedSqmQueryMemento> action);
void registerSqmQueryMemento(String name, NamedSqmQueryMemento descriptor);
NamedSqmQueryMemento<?> getSqmQueryMemento(String queryName);
void visitSqmQueryMementos(Consumer<NamedSqmQueryMemento<?>> action);
void registerSqmQueryMemento(String name, NamedSqmQueryMemento<?> descriptor);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Named NativeQuery Memento
NamedNativeQueryMemento getNativeQueryMemento(String queryName);
void visitNativeQueryMementos(Consumer<NamedNativeQueryMemento> action);
void registerNativeQueryMemento(String name, NamedNativeQueryMemento descriptor);
NamedNativeQueryMemento<?> getNativeQueryMemento(String queryName);
void visitNativeQueryMementos(Consumer<NamedNativeQueryMemento<?>> action);
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.QueryParameterImplementor;
import jakarta.persistence.TypedQueryReference;
/**
* The runtime representation of named queries. They are stored in and
* available through the QueryEngine's {@link NamedObjectRepository}.
@ -23,12 +25,17 @@ import org.hibernate.query.spi.QueryParameterImplementor;
*
* @author Steve Ebersole
*/
public interface NamedQueryMemento {
public interface NamedQueryMemento<E> extends TypedQueryReference<E> {
/**
* The name under which the query is registered
*/
String getRegistrationName();
@Override
default String getName() {
return getRegistrationName();
}
Boolean getCacheable();
String getCacheRegion();
@ -52,9 +59,9 @@ public interface NamedQueryMemento {
/**
* 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);
interface ParameterMemento {

View File

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

View File

@ -81,7 +81,7 @@ public abstract class AbstractSelectionQuery<R>
super( session );
}
protected void applyOptions(NamedQueryMemento memento) {
protected void applyOptions(NamedQueryMemento<?> memento) {
if ( memento.getHints() != null ) {
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.sql.spi.NativeQueryImplementor;
import jakarta.persistence.TypedQueryReference;
import jakarta.persistence.criteria.CriteriaDelete;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.CriteriaUpdate;
@ -38,6 +39,9 @@ public interface QueryProducerImplementor extends QueryProducer {
@Override
<R> QueryImplementor<R> createQuery(String queryString, Class<R> resultClass);
@Override
<R> QueryImplementor<R> createQuery(TypedQueryReference<R> typedQueryReference);
@Override @Deprecated @SuppressWarnings("rawtypes")
QueryImplementor createNamedQuery(String name);

View File

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

View File

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

View File

@ -8,22 +8,17 @@ package org.hibernate.query.sql.spi;
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.query.named.AbstractNamedQueryMemento;
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
*
* @author Steve Ebersole
*/
public interface NamedNativeQueryMemento extends NamedQueryMemento {
public interface NamedNativeQueryMemento<E> extends NamedQueryMemento<E> {
/**
* Informational access to the SQL query string
*/
@ -48,7 +43,9 @@ public interface NamedNativeQueryMemento extends NamedQueryMemento {
/**
* An implicit entity mapping by entity class
*/
Class<?> getResultMappingClass();
default Class<?> getResultMappingClass() {
return getResultType();
}
Integer getFirstResult();
@ -58,7 +55,7 @@ public interface NamedNativeQueryMemento extends NamedQueryMemento {
* Convert the memento into an untyped executable query
*/
@Override
<T> NativeQueryImplementor<T> toQuery(SharedSessionContractImplementor session);
NativeQueryImplementor<E> toQuery(SharedSessionContractImplementor session);
/**
* 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);
@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
NamedNativeQueryMemento toMemento(String name);
NamedNativeQueryMemento<?> toMemento(String name);
@Override
NativeQueryImplementor<R> addScalar(String columnAlias);

View File

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

View File

@ -114,7 +114,7 @@ public class SqmSelectionQueryImpl<R> extends AbstractSqmSelectionQuery<R>
}
public SqmSelectionQueryImpl(
NamedHqlQueryMementoImpl memento,
NamedHqlQueryMementoImpl<?> memento,
Class<R> resultType,
SharedSessionContractImplementor session) {
this(
@ -128,7 +128,7 @@ public class SqmSelectionQueryImpl<R> extends AbstractSqmSelectionQuery<R>
}
public SqmSelectionQueryImpl(
NamedCriteriaQueryMementoImpl memento,
NamedCriteriaQueryMementoImpl<?> memento,
Class<R> expectedResultType,
SharedSessionContractImplementor session) {
//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.tree.SqmStatement;
public interface NamedSqmQueryMemento extends NamedQueryMemento {
public interface NamedSqmQueryMemento<E> extends NamedQueryMemento<E> {
<T> SqmQueryImplementor<T> toQuery(SharedSessionContractImplementor session, Class<T> resultType);
/**
* 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);
String getHqlString();
SqmStatement<?> getSqmStatement();
SqmStatement<E> getSqmStatement();
Integer getFirstResult();
@ -39,6 +39,6 @@ public interface NamedSqmQueryMemento extends NamedQueryMemento {
Map<String, String> getParameterTypes();
@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
public <X> Expression<X> cast(Class<X> castTarget) {
public <X> SqmExpression<X> cast(Class<X> 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"
minOccurs="0">
<xsd:annotation>

View File

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

View File

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

View File

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

View File

@ -31,7 +31,7 @@ public class XmlCacheableNamedQueryTests {
void testCacheableQueryOverride(SessionFactoryScope scope) {
final SessionFactoryImplementor sessionFactory = scope.getSessionFactory();
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.getCacheable() ).isNotNull();
assertThat( queryMemento.getCacheable() ).isTrue();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -31,8 +31,11 @@ import org.hibernate.jpa.HibernatePersistenceProvider;
*/
public class PersistenceUnitInfoImpl implements PersistenceUnitInfo {
private final String name;
private final Properties properties = new Properties();
private String scopeAnnotationName;
private List<String> qualifierAnnotationNames = List.of();
private PersistenceUnitTransactionType transactionType;
private SharedCacheMode cacheMode;
private ValidationMode validationMode;
@ -50,6 +53,24 @@ public class PersistenceUnitInfoImpl implements PersistenceUnitInfo {
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
public Properties getProperties() {
return properties;

View File

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

View File

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

View File

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