HHH-17460 - Ongoing JPA 32 work

HHH-17892 - Remove @Persister
HHH-17893 - Remove MetadataContributor
HHH-17894 - Remove AdditionalJaxbMappingProducer
This commit is contained in:
Steve Ebersole 2024-03-26 20:31:09 -05:00
parent 7d9b425a89
commit 3334534216
29 changed files with 177 additions and 722 deletions

View File

@ -552,34 +552,3 @@ include::{example-dir-proxy}/concrete/AbstractConcreteProxyTest.java[tag=entity-
include::{extrasdir}/entity/entity-concrete-proxy-reference.sql[]
----
====
[[entity-persister]]
==== Define a custom entity persister
The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Persister.html[`@Persister`] annotation is used to specify a custom entity or collection persister.
For entities, the custom persister must implement the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/persister/entity/EntityPersister.html[`EntityPersister`] interface.
For collections, the custom persister must implement the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/persister/collection/CollectionPersister.html[`CollectionPersister`] interface.
NOTE: Supplying a custom persister has been allowed historically, but has never been fully supported.
Hibernate 6 provides better, alternative ways to accomplish the use cases for a custom persister. As
of 6.2 `@Persister` has been formally deprecated.
[[entity-persister-mapping]]
.Entity persister mapping
====
[source,java]
----
include::{example-dir-persister}/Author.java[tag=entity-persister-mapping,indent=0]
----
[source,java]
----
include::{example-dir-persister}/Book.java[tag=entity-persister-mapping,indent=0]
----
====
By providing your own `EntityPersister` and `CollectionPersister` implementations,
you can control how entities and collections are persisted into the database.

View File

@ -59,14 +59,13 @@ import org.hibernate.boot.models.xml.spi.XmlProcessor;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
import org.hibernate.boot.spi.AdditionalJaxbMappingProducer;
import org.hibernate.boot.spi.AdditionalMappingContributions;
import org.hibernate.boot.spi.AdditionalMappingContributor;
import org.hibernate.boot.spi.BootstrapContext;
import org.hibernate.boot.spi.EffectiveMappingDefaults;
import org.hibernate.boot.spi.InFlightMetadataCollector;
import org.hibernate.boot.spi.MappingDefaults;
import org.hibernate.boot.spi.MetadataBuildingOptions;
import org.hibernate.boot.spi.MetadataContributor;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.MetadataSourceType;
@ -236,7 +235,6 @@ public class MetadataBuildingProcess {
);
processAdditionalMappingContributions( metadataCollector, options, classLoaderService, rootMetadataBuildingContext );
processAdditionalJaxbMappingProducer( metadataCollector, options, jandexView, classLoaderService, rootMetadataBuildingContext );
applyExtraQueryImports( managedResources, metadataCollector );
@ -381,11 +379,6 @@ public class MetadataBuildingProcess {
processor.processResultSetMappings();
for ( MetadataContributor contributor : classLoaderService.loadJavaServices( MetadataContributor.class ) ) {
log.tracef( "Calling MetadataContributor : %s", contributor );
contributor.contribute( metadataCollector, jandexView );
}
metadataCollector.processSecondPasses( rootMetadataBuildingContext );
// Make sure collections are fully bound before processing named queries as hbm result set mappings require it
@ -759,6 +752,11 @@ public class MetadataBuildingProcess {
metadataCollector.addAuxiliaryDatabaseObject( auxiliaryDatabaseObject );
}
@Override
public EffectiveMappingDefaults getEffectiveMappingDefaults() {
return rootMetadataBuildingContext.getEffectiveDefaults();
}
public void complete() {
// annotations / orm.xml
if ( additionalEntityClasses != null || additionalClassDetails != null || additionalJaxbMappings != null ) {
@ -781,51 +779,6 @@ public class MetadataBuildingProcess {
}
}
private static void processAdditionalJaxbMappingProducer(
InFlightMetadataCollectorImpl metadataCollector,
MetadataBuildingOptions options,
IndexView jandexView,
ClassLoaderService classLoaderService,
MetadataBuildingContextRootImpl rootMetadataBuildingContext) {
if ( options.isXmlMappingEnabled() ) {
final Iterable<AdditionalJaxbMappingProducer> producers = classLoaderService.loadJavaServices( AdditionalJaxbMappingProducer.class );
if ( producers != null ) {
final EntityHierarchyBuilder hierarchyBuilder = new EntityHierarchyBuilder();
final MappingBinder mappingBinder = new MappingBinder(
classLoaderService,
new MappingBinder.Options() {
@Override
public boolean validateMappings() {
return false;
}
@Override
public boolean transformHbmMappings() {
return false;
}
}
);
//noinspection deprecation
for ( AdditionalJaxbMappingProducer producer : producers ) {
log.tracef( "Calling AdditionalJaxbMappingProducer : %s", producer );
Collection<MappingDocument> additionalMappings = producer.produceAdditionalMappings(
metadataCollector,
jandexView,
mappingBinder,
rootMetadataBuildingContext
);
for ( MappingDocument mappingDocument : additionalMappings ) {
hierarchyBuilder.indexMappingDocument( mappingDocument );
}
}
ModelBinder binder = ModelBinder.prepare( rootMetadataBuildingContext );
for ( EntityHierarchySourceImpl entityHierarchySource : hierarchyBuilder.buildHierarchies() ) {
binder.bindEntityHierarchy( entityHierarchySource );
}
}
}
}
private static void applyExtraQueryImports(
ManagedResources managedResources,

View File

@ -140,7 +140,6 @@ public interface HibernateAnnotations {
AnnotationDescriptor<Parameter> PARAMETER = createOrmDescriptor( Parameter.class );
AnnotationDescriptor<Parent> PARENT = createOrmDescriptor( Parent.class );
AnnotationDescriptor<PartitionKey> PARTITION_KEY = createOrmDescriptor( PartitionKey.class );
AnnotationDescriptor<Persister> PERSISTER = createOrmDescriptor( Persister.class );
AnnotationDescriptor<Polymorphism> POLYMORPHISM = createOrmDescriptor( Polymorphism.class );
AnnotationDescriptor<Proxy> PROXY = createOrmDescriptor( Proxy.class );
AnnotationDescriptor<RowId> ROW_ID = createOrmDescriptor( RowId.class );

View File

@ -1,28 +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.spi;
import java.util.Collection;
import org.hibernate.boot.jaxb.internal.MappingBinder;
import org.hibernate.boot.model.source.internal.hbm.MappingDocument;
import org.jboss.jandex.IndexView;
/**
* @author Steve Ebersole
*
* @deprecated Use {@linkplain AdditionalMappingContributor} instead
*/
@Deprecated
public interface AdditionalJaxbMappingProducer {
Collection<MappingDocument> produceAdditionalMappings(
MetadataImplementor metadata,
IndexView jandexIndex,
MappingBinder mappingBinder,
MetadataBuildingContext buildingContext);
}

View File

@ -69,4 +69,6 @@ public interface AdditionalMappingContributions {
* Contribute a materialized AuxiliaryDatabaseObject
*/
void contributeAuxiliaryDatabaseObject(AuxiliaryDatabaseObject auxiliaryDatabaseObject);
EffectiveMappingDefaults getEffectiveMappingDefaults();
}

View File

@ -1,33 +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.spi;
import org.jboss.jandex.IndexView;
/**
* Contract for contributing to {@link org.hibernate.boot.Metadata} ({@link InFlightMetadataCollector}).
* <p>
* This hook occurs just after all processing of all {@link org.hibernate.boot.MetadataSources},
* and just before {@link AdditionalJaxbMappingProducer}.
*
* @author Steve Ebersole
*
* @since 5.0
*
* @deprecated Use {@link AdditionalMappingContributor} or {@link org.hibernate.boot.model.TypeContributor}
* instead depending on need
*/
@Deprecated(forRemoval = true)
public interface MetadataContributor {
/**
* Perform the contributions.
*
* @param metadataCollector The metadata collector, representing the in-flight metadata being built
* @param jandexIndex The Jandex index
*/
void contribute(InFlightMetadataCollector metadataCollector, IndexView jandexIndex);
}

View File

@ -1,28 +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.orm.test.annotations.persister;
import org.hibernate.annotations.Persister;
import java.io.Serializable;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
/**
* @author Shawn Clowater
*/
@Entity
@Persister( impl = org.hibernate.persister.entity.SingleTableEntityPersister.class )
public class Card implements Serializable {
@Id
public Integer id;
@ManyToOne()
@JoinColumn()
public Deck deck;
}

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.orm.test.annotations.persister;
import org.hibernate.MappingException;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.access.CollectionDataAccess;
import org.hibernate.mapping.Collection;
import org.hibernate.persister.collection.OneToManyPersister;
import org.hibernate.persister.spi.PersisterCreationContext;
/**
* @author Shawn Clowater
*/
public class CollectionPersister extends OneToManyPersister {
public CollectionPersister(
Collection collectionBinding,
CollectionDataAccess cacheAccessStrategy,
PersisterCreationContext creationContext) throws MappingException, CacheException {
super( collectionBinding, cacheAccessStrategy, creationContext );
}
}

View File

@ -1,29 +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.orm.test.annotations.persister;
import java.io.Serializable;
import java.util.Set;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import org.hibernate.annotations.Persister;
/**
* @author Shawn Clowater
*/
@Entity
@Persister( impl = EntityPersister.class )
public class Deck implements Serializable {
@Id
public Integer id;
@OneToMany( mappedBy = "deck" )
@Persister( impl = CollectionPersister.class )
public Set<Card> cards;
}

View File

@ -1,27 +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.orm.test.annotations.persister;
import org.hibernate.HibernateException;
import org.hibernate.cache.spi.access.EntityDataAccess;
import org.hibernate.cache.spi.access.NaturalIdDataAccess;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.persister.entity.SingleTableEntityPersister;
import org.hibernate.persister.spi.PersisterCreationContext;
/**
* @author Shawn Clowater
*/
public class EntityPersister extends SingleTableEntityPersister {
public EntityPersister(
PersistentClass persistentClass,
EntityDataAccess cache,
NaturalIdDataAccess naturalIdRegionAccessStrategy,
PersisterCreationContext creationContext) throws HibernateException {
super( persistentClass, cache, naturalIdRegionAccessStrategy, creationContext );
}
}

View File

@ -6,24 +6,10 @@
*/
package org.hibernate.orm.test.mapping.contributed;
import java.io.InputStream;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import org.hibernate.boot.jaxb.Origin;
import org.hibernate.boot.jaxb.SourceType;
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmHibernateMapping;
import org.hibernate.boot.jaxb.internal.MappingBinder;
import org.hibernate.boot.jaxb.spi.Binding;
import org.hibernate.boot.model.source.internal.hbm.MappingDocument;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.spi.AdditionalJaxbMappingProducer;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.boot.spi.AdditionalMappingContributor;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.H2Dialect;
@ -47,8 +33,6 @@ import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.DomainModelScope;
import org.junit.jupiter.api.Test;
import org.jboss.jandex.IndexView;
import org.hamcrest.Matchers;
import static org.hamcrest.MatcherAssert.assertThat;
@ -58,9 +42,9 @@ import static org.hamcrest.Matchers.not;
* @author Steve Ebersole
*/
@BootstrapServiceRegistry(
javaServices = @JavaService( role = AdditionalJaxbMappingProducer.class, impl = BasicContributorTests.Contributor.class )
javaServices = @JavaService( role = AdditionalMappingContributor.class, impl = ContributorImpl.class )
)
@DomainModel( annotatedClasses = BasicContributorTests.MainEntity.class )
@DomainModel( annotatedClasses = MainEntity.class )
public class BasicContributorTests {
@Test
@ -178,7 +162,14 @@ public class BasicContributorTests {
// filter by `orm`
targetDescriptor.clear();
schemaDropper.doDrop( metadata, options, contributed -> "orm".equals( contributed.getContributor() ), dialect, sourceDescriptor, targetDescriptor );
schemaDropper.doDrop(
metadata,
options,
contributed -> "orm".equals( contributed.getContributor() ),
dialect,
sourceDescriptor,
targetDescriptor
);
assertThat(
targetDescriptor.getCommands(),
CollectionElementMatcher.hasAllOf( not( CaseInsensitiveStartsWithMatcher.startsWith( "drop table DynamicEntity" ) ) )
@ -194,67 +185,4 @@ public class BasicContributorTests {
}
@Entity( name = "MainEntity" )
@Table( name = "main_table" )
static class MainEntity {
@Id
private Integer id;
String name;
private MainEntity() {
}
public MainEntity(Integer id, String name) {
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public static class Contributor implements AdditionalJaxbMappingProducer {
public Contributor() {
}
@Override
public Collection<MappingDocument> produceAdditionalMappings(
MetadataImplementor metadata,
IndexView jandexIndex,
MappingBinder mappingBinder,
MetadataBuildingContext buildingContext) {
return Collections.singletonList( createMappingDocument( mappingBinder, buildingContext ) );
}
private MappingDocument createMappingDocument(MappingBinder mappingBinder, MetadataBuildingContext buildingContext) {
final Origin origin = new Origin( SourceType.OTHER, "test" );
final ClassLoaderService classLoaderService = buildingContext.getBootstrapContext()
.getServiceRegistry()
.getService( ClassLoaderService.class );
final InputStream inputStream = classLoaderService.locateResourceStream( "org/hibernate/orm/test/mapping/contributed/BasicContributorTests.hbm.xml" );
final Binding<JaxbHbmHibernateMapping> jaxbBinding = mappingBinder.bind( inputStream, origin );
final JaxbHbmHibernateMapping jaxbRoot = jaxbBinding.getRoot();
return new MappingDocument(
"test",
jaxbRoot,
origin,
buildingContext
);
}
}
}

View File

@ -0,0 +1,57 @@
/*
* 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.mapping.contributed;
import java.io.InputStream;
import org.hibernate.boot.ResourceStreamLocator;
import org.hibernate.boot.jaxb.Origin;
import org.hibernate.boot.jaxb.SourceType;
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmHibernateMapping;
import org.hibernate.boot.jaxb.internal.MappingBinder;
import org.hibernate.boot.jaxb.spi.Binding;
import org.hibernate.boot.model.source.internal.hbm.MappingDocument;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.spi.AdditionalMappingContributions;
import org.hibernate.boot.spi.AdditionalMappingContributor;
import org.hibernate.boot.spi.InFlightMetadataCollector;
import org.hibernate.boot.spi.MetadataBuildingContext;
/**
* @author Steve Ebersole
*/
public class ContributorImpl implements AdditionalMappingContributor {
public ContributorImpl() {
}
@Override
public String getContributorName() {
return "test";
}
@Override
public void contribute(
AdditionalMappingContributions contributions,
InFlightMetadataCollector metadata,
ResourceStreamLocator resourceStreamLocator,
MetadataBuildingContext buildingContext) {
final Origin origin = new Origin( SourceType.OTHER, "test" );
final ClassLoaderService classLoaderService = buildingContext.getBootstrapContext()
.getServiceRegistry()
.getService( ClassLoaderService.class );
final InputStream inputStream = classLoaderService.locateResourceStream(
"org/hibernate/orm/test/mapping/contributed/BasicContributorTests.hbm.xml" );
final MappingBinder mappingBinder = new MappingBinder( buildingContext.getBootstrapContext().getServiceRegistry() );
final Binding<JaxbHbmHibernateMapping> jaxbBinding = mappingBinder.bind( inputStream, origin );
final JaxbHbmHibernateMapping jaxbRoot = jaxbBinding.getRoot();
contributions.contributeBinding( jaxbRoot );
}
}

View File

@ -6,7 +6,7 @@
*/
package org.hibernate.orm.test.mapping.contributed;
import org.hibernate.boot.spi.AdditionalJaxbMappingProducer;
import org.hibernate.boot.spi.AdditionalMappingContributor;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.metamodel.RuntimeMetamodels;
@ -14,6 +14,7 @@ import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.testing.orm.junit.BootstrapServiceRegistry;
import org.hibernate.testing.orm.junit.BootstrapServiceRegistry.JavaService;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.NotImplementedYet;
import org.hibernate.testing.orm.junit.ServiceRegistry;
@ -28,16 +29,15 @@ import static org.hamcrest.Matchers.nullValue;
/**
* @author Steve Ebersole
*/
@BootstrapServiceRegistry(
javaServices = @BootstrapServiceRegistry.JavaService( role = AdditionalJaxbMappingProducer.class, impl = BasicContributorTests.Contributor.class )
@BootstrapServiceRegistry( javaServices = @JavaService(
role = AdditionalMappingContributor.class,
impl = ContributorImpl.class )
)
@ServiceRegistry(
settings = @Setting(
name = AvailableSettings.JPA_METAMODEL_POPULATION,
value = "ignoreUnsupported"
)
)
@DomainModel( annotatedClasses = BasicContributorTests.MainEntity.class )
@ServiceRegistry( settings = @Setting(
name = AvailableSettings.JPA_METAMODEL_POPULATION,
value = "ignoreUnsupported"
) )
@DomainModel( annotatedClasses = MainEntity.class )
@SessionFactory
public class EntityHidingTests {
@Test

View File

@ -0,0 +1,46 @@
/*
* 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.mapping.contributed;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
/**
* @author Steve Ebersole
*/
@Entity(name = "MainEntity")
@Table(name = "main_table")
class MainEntity {
@Id
private Integer id;
String name;
private MainEntity() {
}
public MainEntity(Integer id, String name) {
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -6,31 +6,19 @@
*/
package org.hibernate.orm.test.mapping.converted.converter.custom;
import java.util.List;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.model.TypeContributions;
import org.hibernate.boot.model.TypeContributor;
import org.hibernate.boot.registry.BootstrapServiceRegistry;
import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.spi.InFlightMetadataCollector;
import org.hibernate.boot.spi.MetadataBuilderImplementor;
import org.hibernate.boot.spi.MetadataContributor;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.tool.schema.Action;
import org.hibernate.type.spi.TypeConfiguration;
import org.hibernate.testing.boot.ExtraJavaServicesClassLoaderService;
import org.hibernate.testing.boot.ExtraJavaServicesClassLoaderService.JavaServiceDescriptor;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.hibernate.testing.util.ServiceRegistryUtil;
import org.junit.Test;
import org.jboss.jandex.IndexView;
import org.hibernate.testing.orm.junit.BootstrapServiceRegistry;
import org.hibernate.testing.orm.junit.BootstrapServiceRegistry.JavaService;
import org.hibernate.testing.orm.junit.ServiceRegistryScope;
import org.junit.jupiter.api.Test;
import static org.hamcrest.CoreMatchers.sameInstance;
import static org.hamcrest.MatcherAssert.assertThat;
@ -38,31 +26,21 @@ import static org.hamcrest.MatcherAssert.assertThat;
/**
* @author Steve Ebersole
*/
public class CustomTypeConverterTest extends BaseUnitTestCase {
public class CustomTypeConverterTest {
@Test
public void testConverterAppliedScopedRegistration() {
final List<JavaServiceDescriptor<?>> services = List.of(
new JavaServiceDescriptor<>(
MetadataContributor.class,
PayloadWrapperMetadataContributor.class
)
);
final BootstrapServiceRegistry bsr = new BootstrapServiceRegistryBuilder().enableAutoClose()
.applyClassLoaderService( new ExtraJavaServicesClassLoaderService( services ) )
.build();
try (final StandardServiceRegistry ssr = ServiceRegistryUtil.serviceRegistryBuilder( bsr )
.applySetting( AvailableSettings.HBM2DDL_AUTO, Action.CREATE_DROP )
.build() ) {
final MetadataSources metadataSources = new MetadataSources( ssr )
.addAnnotatedClass( PayloadWrapperConverter.class )
.addAnnotatedClass( MyEntity.class );
final MetadataBuilderImplementor metadataBuilder = (MetadataBuilderImplementor) metadataSources.getMetadataBuilder();
// now the new scoped way
final TypeConfiguration bootTypeConfiguration = metadataBuilder.getBootstrapContext().getTypeConfiguration();
performAssertions( metadataBuilder, bootTypeConfiguration );
}
@BootstrapServiceRegistry( javaServices = @JavaService(
role = TypeContributor.class,
impl = PayloadWrapperTypeContributorImpl.class
) )
@SuppressWarnings("JUnitMalformedDeclaration")
public void testConverterAppliedScopedContributions(ServiceRegistryScope registryScope) {
final MetadataSources metadataSources = new MetadataSources( registryScope.getRegistry() )
.addAnnotatedClass( PayloadWrapperConverter.class )
.addAnnotatedClass( MyEntity.class );
final MetadataBuilderImplementor metadataBuilder = (MetadataBuilderImplementor) metadataSources.getMetadataBuilder();
final TypeConfiguration bootTypeConfiguration = metadataBuilder.getBootstrapContext().getTypeConfiguration();
performAssertions( metadataBuilder, bootTypeConfiguration );
}
protected void performAssertions(
@ -89,41 +67,6 @@ public class CustomTypeConverterTest extends BaseUnitTestCase {
}
}
@Test
public void testConverterAppliedScopedContributions() {
final List<JavaServiceDescriptor<?>> services = List.of(
new JavaServiceDescriptor<>( TypeContributor.class, PayloadWrapperTypeContributorImpl.class )
);
final BootstrapServiceRegistry bsr = new BootstrapServiceRegistryBuilder().enableAutoClose()
.applyClassLoaderService( new ExtraJavaServicesClassLoaderService( services ) )
.build();
try ( final StandardServiceRegistry ssr = ServiceRegistryUtil.serviceRegistryBuilder( bsr )
.applySetting( AvailableSettings.HBM2DDL_AUTO, Action.CREATE_DROP )
.build() ) {
final MetadataSources metadataSources = new MetadataSources( ssr )
.addAnnotatedClass( PayloadWrapperConverter.class )
.addAnnotatedClass( MyEntity.class );
final MetadataBuilderImplementor metadataBuilder = (MetadataBuilderImplementor) metadataSources.getMetadataBuilder();
// now the new scoped way
final TypeConfiguration bootTypeConfiguration = metadataBuilder.getBootstrapContext().getTypeConfiguration();
performAssertions( metadataBuilder, bootTypeConfiguration );
}
}
public static class PayloadWrapperMetadataContributor implements MetadataContributor {
@Override
public void contribute(InFlightMetadataCollector metadataCollector, IndexView jandexIndex) {
final TypeConfiguration typeConfiguration = metadataCollector.getTypeConfiguration();
typeConfiguration.getJavaTypeRegistry()
.addDescriptor( PayloadWrapperJavaType.INSTANCE );
typeConfiguration.getJdbcTypeRegistry()
.addDescriptor( PayloadWrapperJdbcType.INSTANCE );
}
}
public static class PayloadWrapperTypeContributorImpl implements TypeContributor {
@Override
public void contribute(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {

View File

@ -1,55 +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.orm.test.persister;
import java.util.HashSet;
import java.util.Set;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import org.hibernate.annotations.Persister;
/**
* @author Shawn Clowater
*/
//tag::entity-persister-mapping[]
@Entity
@Persister(impl = EntityPersister.class)
public class Author {
@Id
public Integer id;
@OneToMany(mappedBy = "author")
@Persister(impl = CollectionPersister.class)
public Set<Book> books = new HashSet<>();
//Getters and setters omitted for brevity
//end::entity-persister-mapping[]
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Set<Book> getBooks() {
return books;
}
//tag::entity-persister-mapping[]
public void addBook(Book book) {
this.books.add(book);
book.setAuthor(this);
}
}
//end::entity-persister-mapping[]

View File

@ -1,61 +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.orm.test.persister;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;
import org.hibernate.annotations.Persister;
/**
* @author Shawn Clowater
*/
//tag::entity-persister-mapping[]
@Entity
@Persister(impl = EntityPersister.class)
public class Book {
@Id
public Integer id;
private String title;
@ManyToOne(fetch = FetchType.LAZY)
public Author author;
//Getters and setters omitted for brevity
//end::entity-persister-mapping[]
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Author getAuthor() {
return author;
}
public void setAuthor(Author author) {
this.author = author;
}
//tag::entity-persister-mapping[]
}
//end::entity-persister-mapping[]

View File

@ -1,32 +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.orm.test.persister;
import org.hibernate.MappingException;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.access.CollectionDataAccess;
import org.hibernate.mapping.Collection;
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
import org.hibernate.persister.collection.OneToManyPersister;
/**
* @author Shawn Clowater
*/
//tag::entity-persister-mapping[]
public class CollectionPersister
extends OneToManyPersister {
public CollectionPersister(
Collection collectionBinding,
CollectionDataAccess cacheAccessStrategy,
RuntimeModelCreationContext creationContext)
throws MappingException, CacheException {
super(collectionBinding, cacheAccessStrategy, creationContext);
}
}
//end::entity-persister-mapping[]

View File

@ -1,34 +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.orm.test.persister;
import org.hibernate.HibernateException;
import org.hibernate.cache.spi.access.EntityDataAccess;
import org.hibernate.cache.spi.access.NaturalIdDataAccess;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
import org.hibernate.persister.entity.SingleTableEntityPersister;
/**
* @author Shawn Clowater
*/
//tag::entity-persister-mapping[]
public class EntityPersister
extends SingleTableEntityPersister {
public EntityPersister(
PersistentClass persistentClass,
EntityDataAccess cache,
NaturalIdDataAccess naturalIdRegionAccessStrategy,
RuntimeModelCreationContext creationContext)
throws HibernateException {
super(persistentClass, cache, naturalIdRegionAccessStrategy, creationContext);
}
}
//end::entity-persister-mapping[]

View File

@ -2,20 +2,18 @@
* 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>.
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html.
*/
package org.hibernate.orm.test.persister.entity;
import org.hibernate.annotations.Loader;
import org.hibernate.annotations.NamedNativeQuery;
import org.hibernate.annotations.Persister;
import org.hibernate.annotations.ResultCheckStyle;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.SQLInsert;
import org.hibernate.annotations.SQLUpdate;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.persister.entity.AbstractEntityPersister;
import org.hibernate.persister.entity.SingleTableEntityPersister;
import org.hibernate.sql.model.jdbc.JdbcMutationOperation;
import org.hibernate.testing.orm.junit.DomainModel;
@ -89,7 +87,6 @@ public class CustomSqlSchemaResolvingIdentityTest {
}
@Entity(name = "CardWithCustomSQL")
@Persister( impl = SingleTableEntityPersister.class )
@Loader(namedQuery = "find_foo_by_id")
@NamedNativeQuery(
name = "find_foo_by_id",

View File

@ -2,19 +2,17 @@
* 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>.
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html.
*/
package org.hibernate.orm.test.persister.entity;
import org.hibernate.annotations.Loader;
import org.hibernate.annotations.NamedNativeQuery;
import org.hibernate.annotations.Persister;
import org.hibernate.annotations.ResultCheckStyle;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.SQLInsert;
import org.hibernate.annotations.SQLUpdate;
import org.hibernate.persister.entity.AbstractEntityPersister;
import org.hibernate.persister.entity.SingleTableEntityPersister;
import org.hibernate.sql.model.jdbc.JdbcMutationOperation;
import org.hibernate.testing.orm.junit.DomainModel;
@ -83,7 +81,6 @@ public class CustomSqlSchemaResolvingTest {
}
@Entity(name = "CardWithCustomSQL")
@Persister( impl = SingleTableEntityPersister.class )
@Loader(namedQuery = "find_foo_by_id")
@NamedNativeQuery(
name = "find_foo_by_id",

View File

@ -1,96 +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.envers.boot.internal;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import org.hibernate.HibernateException;
import org.hibernate.boot.jaxb.Origin;
import org.hibernate.boot.jaxb.SourceType;
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmHibernateMapping;
import org.hibernate.boot.jaxb.internal.MappingBinder;
import org.hibernate.boot.model.source.internal.hbm.MappingDocument;
import org.hibernate.boot.spi.AdditionalJaxbMappingProducer;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.boot.spi.MetadataBuildingOptions;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.envers.boot.EnversBootLogger;
import org.hibernate.envers.configuration.internal.MappingCollector;
import org.hibernate.service.ServiceRegistry;
import org.jboss.jandex.IndexView;
import org.jboss.logging.Logger;
import static org.hibernate.cfg.AvailableSettings.XML_MAPPING_ENABLED;
import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.Marshaller;
/**
* @author Steve Ebersole
* @author Chris Cranford
*/
public class AdditionalJaxbMappingProducerImpl implements AdditionalJaxbMappingProducer {
private static final Logger log = Logger.getLogger( AdditionalJaxbMappingProducerImpl.class );
@Override
public Collection<MappingDocument> produceAdditionalMappings(
final MetadataImplementor metadata,
IndexView jandexIndex,
final MappingBinder mappingBinder,
final MetadataBuildingContext buildingContext) {
MetadataBuildingOptions metadataBuildingOptions = metadata.getMetadataBuildingOptions();
final ServiceRegistry serviceRegistry = metadataBuildingOptions.getServiceRegistry();
final EnversService enversService = serviceRegistry.getService( EnversService.class );
if ( !enversService.isEnabled() ) {
// short-circuit if envers integration has been disabled.
return Collections.emptyList();
}
if ( !metadataBuildingOptions.isXmlMappingEnabled() ) {
throw new HibernateException( "Hibernate Envers currently requires XML mapping to be enabled."
+ " Please don't disable setting `" + XML_MAPPING_ENABLED
+ "`; alternatively disable Hibernate Envers." );
}
final ArrayList<MappingDocument> additionalMappingDocuments = new ArrayList<>();
// atm we do not have distinct origin info for envers
final Origin origin = new Origin( SourceType.OTHER, "envers" );
final MappingCollector mappingCollector = new MappingCollector() {
@Override
public void addDocument(JaxbHbmHibernateMapping mapping) {
log.infof( "Adding JAXB document mapping" );
try {
JAXBContext context = JAXBContext.newInstance( JaxbHbmHibernateMapping.class );
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty ( Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE );
StringWriter sw = new StringWriter();
marshaller.marshal( mapping, sw );
EnversBootLogger.BOOT_LOGGER.jaxbContribution( sw.toString() );
log.trace( "------------------------------------------------------------" );
}
catch (JAXBException e) {
throw new RuntimeException( "Error dumping enhanced class", e );
}
additionalMappingDocuments.add( new MappingDocument( "envers", mapping, origin, buildingContext ) );
}
};
enversService.initialize( metadata, mappingCollector );
return additionalMappingDocuments;
}
}

View File

@ -47,6 +47,6 @@ public class AdditionalMappingContributorImpl implements AdditionalMappingContri
+ "`; alternatively disable Hibernate Envers." );
}
enversService.initialize( metadata, contributions::contributeBinding );
enversService.initialize( metadata, contributions::contributeBinding, contributions.getEffectiveMappingDefaults() );
}
}

View File

@ -10,8 +10,8 @@ import org.hibernate.annotations.common.reflection.ReflectionManager;
import org.hibernate.boot.model.TypeDefinitionRegistry;
import org.hibernate.boot.model.naming.ObjectNameNormalizer;
import org.hibernate.boot.spi.BootstrapContext;
import org.hibernate.boot.spi.EffectiveMappingDefaults;
import org.hibernate.boot.spi.InFlightMetadataCollector;
import org.hibernate.boot.spi.MappingDefaults;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.boot.spi.MetadataBuildingOptions;
import org.hibernate.envers.boot.spi.EnversMetadataBuildingContext;
@ -30,6 +30,7 @@ public class EnversMetadataBuildingContextImpl implements EnversMetadataBuilding
private final Configuration configuration;
private final InFlightMetadataCollector metadataCollector;
private final EffectiveMappingDefaults effectiveMappingDefaults;
private final MappingCollector mappingCollector;
private final ObjectNameNormalizer objectNameNormalizer;
private final AuditEntityNameRegister auditEntityNameRegistry;
@ -38,9 +39,11 @@ public class EnversMetadataBuildingContextImpl implements EnversMetadataBuilding
public EnversMetadataBuildingContextImpl(
Configuration configuration,
InFlightMetadataCollector metadataCollector,
EffectiveMappingDefaults effectiveMappingDefaults,
MappingCollector mappingCollector) {
this.configuration = configuration;
this.metadataCollector = metadataCollector;
this.effectiveMappingDefaults = effectiveMappingDefaults;
this.mappingCollector = mappingCollector;
this.auditEntityNameRegistry = new AuditEntityNameRegister();
this.auditEntityConfigurationRegistry = new AuditEntityConfigurationRegistry();
@ -64,8 +67,8 @@ public class EnversMetadataBuildingContextImpl implements EnversMetadataBuilding
}
@Override
public MappingDefaults getEffectiveDefaults() {
return metadataCollector.getMetadataBuildingOptions().getMappingDefaults();
public EffectiveMappingDefaults getEffectiveDefaults() {
return effectiveMappingDefaults;
}
@Override

View File

@ -7,6 +7,7 @@
package org.hibernate.envers.boot.internal;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.spi.EffectiveMappingDefaults;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.envers.configuration.Configuration;
import org.hibernate.envers.configuration.internal.MappingCollector;
@ -53,7 +54,10 @@ public interface EnversService extends Service {
*/
boolean isInitialized();
void initialize(MetadataImplementor metadata, MappingCollector mappingCollector);
void initialize(
MetadataImplementor metadata,
MappingCollector mappingCollector,
EffectiveMappingDefaults effectiveMappingDefaults);
Configuration getConfig();

View File

@ -10,6 +10,7 @@ import java.util.Map;
import java.util.Properties;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.spi.EffectiveMappingDefaults;
import org.hibernate.boot.spi.InFlightMetadataCollector;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.engine.config.spi.ConfigurationService;
@ -87,7 +88,10 @@ public class EnversServiceImpl implements EnversService, Configurable, Stoppable
}
@Override
public void initialize(MetadataImplementor metadata, MappingCollector mappingCollector) {
public void initialize(
MetadataImplementor metadata,
MappingCollector mappingCollector,
EffectiveMappingDefaults effectiveMappingDefaults) {
if ( initialized ) {
throw new UnsupportedOperationException( "EnversService#initialize should be called only once" );
}
@ -107,6 +111,7 @@ public class EnversServiceImpl implements EnversService, Configurable, Stoppable
final EnversMetadataBuildingContext metadataBuildingContext = new EnversMetadataBuildingContextImpl(
configuration,
(InFlightMetadataCollector) metadata,
effectiveMappingDefaults,
mappingCollector
);

View File

@ -22,8 +22,8 @@
<bean id="serviceContributor" class="org.hibernate.envers.boot.internal.EnversServiceContributor"/>
<service ref="serviceContributor" interface="org.hibernate.service.spi.ServiceContributor"/>
<bean id="additionalJaxbMappingProducer" class="org.hibernate.envers.boot.internal.AdditionalJaxbMappingProducerImpl"/>
<service ref="additionalJaxbMappingProducer" interface="org.hibernate.boot.spi.AdditionalJaxbMappingProducer"/>
<bean id="additionalMappingContributor" class="org.hibernate.envers.boot.internal.AdditionalMappingContributorImpl"/>
<service ref="additionalMappingContributor" interface="org.hibernate.boot.spi.AdditionalMappingContributor"/>
<bean id="modifiedColumnNamingStrategyRegistrationProducer" class="org.hibernate.envers.boot.internal.ModifiedColumnNamingStrategyRegistrationProvider"/>
<service ref="modifiedColumnNamingStrategyRegistrationProducer" interface="org.hibernate.boot.registry.selector.StrategyRegistrationProvider"/>

View File

@ -39,5 +39,5 @@ logger.jdbc-bind.level=trace
logger.jdbc-extract.name=org.hibernate.orm.jdbc.extract
logger.jdbc-extract.level=trace
logger.additional-jaxb-mapping-producer-impl.name=org.hibernate.envers.boot.internal.AdditionalJaxbMappingProducerImpl
logger.additional-jaxb-mapping-producer-impl.level=trace
logger.envers-mappings-producer.name=org.hibernate.envers.boot.internal.AdditionalMappingContributorImpl
logger.envers-mappings-producer.level=trace

View File

@ -2,7 +2,7 @@
:toc:
:toclevels: 4
:docsBase: https://docs.jboss.org/hibernate/orm
:versionDocBase: {docsBase}/6.4
:versionDocBase: {docsBase}/7.0
:userGuideBase: {versionDocBase}/userguide/html_single/Hibernate_User_Guide.html
:javadocsBase: {versionDocBase}/javadocs
@ -67,6 +67,8 @@ private Employee manager;
== Some Cleanup
* Removed `SqmQualifiedJoin`. All joins are qualified.
* Removed `AdditionalJaxbMappingProducer`, deprecated in favor of `AdditionalMappingContributor`
* Removed `MetadataContributor`, deprecated in favor of `AdditionalMappingContributor`
[[todo]]
@ -74,7 +76,6 @@ private Employee manager;
NOTE:: Look for `// todo (jpa 3.2)`
* Deprecate `SqmQualifiedJoin` in 6.x
* {@linkplain SqmCrossJoin} and its offspring are largely de-typed to account
for {@linkplain SqmCrossJoin} having only one type argument for the right-hand
side. To properly handle the type parameters in the hierarchy we need to change this to