HHH-17460 - Ongoing JPA 32 work

This commit is contained in:
Steve Ebersole 2024-03-26 13:00:20 -05:00
parent 38de392b2b
commit aededc93a2
7 changed files with 136 additions and 5 deletions

View File

@ -203,7 +203,7 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector,
this.uuid = UUID.randomUUID();
this.globalRegistrations = new GlobalRegistrationsImpl( sourceModelBuildingContext );
this.globalRegistrations = new GlobalRegistrationsImpl( sourceModelBuildingContext, bootstrapContext );
this.persistenceUnitMetadata = new PersistenceUnitMetadataImpl();
for ( Map.Entry<String, SqmFunctionDescriptor> sqlFunctionEntry : bootstrapContext.getSqlFunctions().entrySet() ) {

View File

@ -70,6 +70,9 @@ import org.hibernate.boot.models.categorize.spi.SqlResultSetMappingRegistration;
import org.hibernate.boot.models.categorize.spi.TableGeneratorRegistration;
import org.hibernate.boot.models.categorize.spi.UserTypeRegistration;
import org.hibernate.boot.models.xml.internal.XmlAnnotationHelper;
import org.hibernate.boot.spi.BootstrapContext;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.jpa.AvailableHints;
@ -116,6 +119,7 @@ import static org.hibernate.internal.util.collections.CollectionHelper.isEmpty;
*/
public class GlobalRegistrationsImpl implements GlobalRegistrations {
private final SourceModelBuildingContext sourceModelContext;
private final BootstrapContext bootstrapContext;
private List<JpaEventListener> jpaEventListeners;
private List<ConversionRegistration> converterRegistrations;
@ -139,8 +143,9 @@ public class GlobalRegistrationsImpl implements GlobalRegistrations {
private Map<String, NamedNativeQueryRegistration> namedNativeQueryRegistrations;
private Map<String, NamedStoredProcedureQueryRegistration> namedStoredProcedureQueryRegistrations;
public GlobalRegistrationsImpl(SourceModelBuildingContext sourceModelContext) {
public GlobalRegistrationsImpl(SourceModelBuildingContext sourceModelContext, BootstrapContext bootstrapContext) {
this.sourceModelContext = sourceModelContext;
this.bootstrapContext = bootstrapContext;
}
@Override
@ -696,6 +701,8 @@ public class GlobalRegistrationsImpl implements GlobalRegistrations {
}
public void collectSequenceGenerator(SequenceGeneratorRegistration generatorRegistration) {
checkGeneratorName( generatorRegistration.name() );
if ( sequenceGeneratorRegistrations == null ) {
sequenceGeneratorRegistrations = new HashMap<>();
}
@ -703,6 +710,26 @@ public class GlobalRegistrationsImpl implements GlobalRegistrations {
sequenceGeneratorRegistrations.put( generatorRegistration.name(), generatorRegistration );
}
private void checkGeneratorName(String name) {
checkGeneratorName( name, sequenceGeneratorRegistrations );
checkGeneratorName( name, tableGeneratorRegistrations );
checkGeneratorName( name, genericGeneratorRegistrations );
}
private void checkGeneratorName(String name, Map<String, ?> generatorMap) {
if ( generatorMap == null ) {
return;
}
if ( generatorMap.containsKey( name ) ) {
if ( bootstrapContext.getJpaCompliance().isGlobalGeneratorScopeEnabled() ) {
throw new IllegalArgumentException( "Duplicate generator name " + name + "; you will likely want to set the property " + AvailableSettings.JPA_ID_GENERATOR_GLOBAL_SCOPE_COMPLIANCE + " to false " );
}
else {
CoreLogging.messageLogger( GlobalRegistrationsImpl.class ).duplicateGeneratorName( name );
}
}
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Table generator
@ -736,6 +763,7 @@ public class GlobalRegistrationsImpl implements GlobalRegistrations {
}
public void collectTableGenerator(TableGeneratorRegistration generatorRegistration) {
checkGeneratorName( generatorRegistration.name() );
if ( tableGeneratorRegistrations == null ) {
tableGeneratorRegistrations = new HashMap<>();
}
@ -770,6 +798,8 @@ public class GlobalRegistrationsImpl implements GlobalRegistrations {
}
public void collectGenericGenerator(GenericGeneratorRegistration generatorRegistration) {
checkGeneratorName( generatorRegistration.name() );
if ( genericGeneratorRegistrations == null ) {
genericGeneratorRegistrations = new HashMap<>();
}
@ -952,17 +982,20 @@ public class GlobalRegistrationsImpl implements GlobalRegistrations {
final MutableAnnotationUsage<QueryHint> cacheableHint = makeAnnotation( JpaAnnotations.QUERY_HINT );
cacheableHint.setAttributeValue( "name", AvailableHints.HINT_CACHEABLE );
cacheableHint.setAttributeValue( "value", Boolean.TRUE.toString() );
hints.add( cacheableHint );
if ( jaxbNamedQuery.getCacheMode() != null ) {
final MutableAnnotationUsage<QueryHint> hint = makeAnnotation( JpaAnnotations.QUERY_HINT );
hint.setAttributeValue( "name", AvailableHints.HINT_CACHE_MODE );
hint.setAttributeValue( "value", jaxbNamedQuery.getCacheMode().name() );
hints.add( hint );
}
if ( isNotEmpty( jaxbNamedQuery.getCacheRegion() ) ) {
final MutableAnnotationUsage<QueryHint> hint = makeAnnotation( JpaAnnotations.QUERY_HINT );
hint.setAttributeValue( "name", AvailableHints.HINT_CACHE_REGION );
hint.setAttributeValue( "value", jaxbNamedQuery.getCacheRegion() );
hints.add( hint );
}
}
@ -970,24 +1003,28 @@ public class GlobalRegistrationsImpl implements GlobalRegistrations {
final MutableAnnotationUsage<QueryHint> hint = makeAnnotation( JpaAnnotations.QUERY_HINT );
hint.setAttributeValue( "name", AvailableHints.HINT_COMMENT );
hint.setAttributeValue( "value", jaxbNamedQuery.getComment() );
hints.add( hint );
}
if ( jaxbNamedQuery.getFetchSize() != null ) {
final MutableAnnotationUsage<QueryHint> hint = makeAnnotation( JpaAnnotations.QUERY_HINT );
hint.setAttributeValue( "name", AvailableHints.HINT_FETCH_SIZE );
hint.setAttributeValue( "value", jaxbNamedQuery.getFetchSize().toString() );
hints.add( hint );
}
if ( jaxbNamedQuery.isReadOnly() == Boolean.TRUE ) {
final MutableAnnotationUsage<QueryHint> hint = makeAnnotation( JpaAnnotations.QUERY_HINT );
hint.setAttributeValue( "name", AvailableHints.HINT_READ_ONLY );
hint.setAttributeValue( "value", Boolean.TRUE.toString() );
hints.add( hint );
}
if ( jaxbNamedQuery.getFlushMode() != null ) {
final MutableAnnotationUsage<QueryHint> hint = makeAnnotation( JpaAnnotations.QUERY_HINT );
hint.setAttributeValue( "name", AvailableHints.HINT_FLUSH_MODE );
hint.setAttributeValue( "value", jaxbNamedQuery.getFlushMode().name() );
hints.add( hint );
}
}
}

View File

@ -14,7 +14,6 @@ import java.util.stream.Collectors;
import org.hibernate.Internal;
import org.hibernate.annotations.TenantId;
import org.hibernate.boot.internal.BootstrapContextImpl;
import org.hibernate.boot.internal.MetadataBuilderImpl;
import org.hibernate.boot.internal.RootMappingDefaults;
import org.hibernate.boot.model.process.spi.ManagedResources;
@ -137,7 +136,7 @@ public class ManagedResourcesProcessor {
final boolean areIdGeneratorsGlobal = true;
final ClassDetailsRegistry classDetailsRegistry = sourceModelBuildingContext.getClassDetailsRegistry();
final AnnotationDescriptorRegistry descriptorRegistry = sourceModelBuildingContext.getAnnotationDescriptorRegistry();
final GlobalRegistrationsImpl globalRegistrations = new GlobalRegistrationsImpl( sourceModelBuildingContext );
final GlobalRegistrationsImpl globalRegistrations = new GlobalRegistrationsImpl( sourceModelBuildingContext, bootstrapContext );
final DomainModelCategorizationCollector modelCategorizationCollector = new DomainModelCategorizationCollector(
areIdGeneratorsGlobal,
globalRegistrations,

View File

@ -23,6 +23,7 @@ import org.hibernate.models.spi.SourceModelBuildingContext;
import org.hibernate.orm.test.boot.models.XmlHelper;
import org.hibernate.type.descriptor.jdbc.ClobJdbcType;
import org.hibernate.testing.boot.BootstrapContextImpl;
import org.junit.jupiter.api.Test;
import static jakarta.persistence.AccessType.FIELD;
@ -126,7 +127,7 @@ public class XmlProcessingSmokeTests {
final DomainModelCategorizationCollector collector = new DomainModelCategorizationCollector(
false,
new GlobalRegistrationsImpl( buildingContext ),
new GlobalRegistrationsImpl( buildingContext, new BootstrapContextImpl() ),
null,
buildingContext
);

View File

@ -0,0 +1,47 @@
/*
* 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.orm.test.hbm.query;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Basic;
import jakarta.persistence.NamedQuery;
/**
* @author Steve Ebersole
*/
@Entity
@NamedQuery(name = SimpleEntity.FIND_ALL, query = "from SimpleEntity")
public class SimpleEntity {
public static final String FIND_ALL = "SimpleEntity.findAll";
@Id
private Integer id;
@Basic
private String name;
protected SimpleEntity() {
// for Hibernate use
}
public SimpleEntity(Integer id, String name) {
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,39 @@
/*
* 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.orm.test.hbm.query;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.query.named.NamedObjectRepository;
import org.hibernate.query.sqm.spi.NamedSqmQueryMemento;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Steve Ebersole
*/
public class XmlCacheableNamedQueryTests {
@Test
@DomainModel(
annotatedClasses = SimpleEntity.class,
xmlMappings = "org/hibernate/orm/test/hbm/query/CacheableNamedQueryOverride.xml"
)
@SessionFactory
@SuppressWarnings("JUnitMalformedDeclaration")
void testCacheableQueryOverride(SessionFactoryScope scope) {
final SessionFactoryImplementor sessionFactory = scope.getSessionFactory();
final NamedObjectRepository namedObjectRepository = sessionFactory.getQueryEngine().getNamedObjectRepository();
final NamedSqmQueryMemento queryMemento = namedObjectRepository.getSqmQueryMemento( SimpleEntity.FIND_ALL );
assertThat( queryMemento ).isNotNull();
assertThat( queryMemento.getCacheable() ).isNotNull();
assertThat( queryMemento.getCacheable() ).isTrue();
}
}

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://www.hibernate.org/xsd/orm/mapping" version="7.0">
<named-query name="SimpleEntity.findAll">
<query>from SimpleEntity</query>
<cacheable>true</cacheable>
</named-query>
</entity-mappings>