HHH-16006 - Implement an "additional mapping" contributor SPI
This commit is contained in:
parent
ab86055565
commit
a9ef9045f2
|
@ -18,11 +18,16 @@ import java.util.Set;
|
|||
import org.hibernate.boot.MetadataSources;
|
||||
import org.hibernate.boot.internal.InFlightMetadataCollectorImpl;
|
||||
import org.hibernate.boot.internal.MetadataBuildingContextRootImpl;
|
||||
import org.hibernate.boot.jaxb.Origin;
|
||||
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmHibernateMapping;
|
||||
import org.hibernate.boot.jaxb.internal.MappingBinder;
|
||||
import org.hibernate.boot.model.TypeContributions;
|
||||
import org.hibernate.boot.model.TypeContributor;
|
||||
import org.hibernate.boot.model.process.internal.ManagedResourcesImpl;
|
||||
import org.hibernate.boot.model.process.internal.ScanningCoordinator;
|
||||
import org.hibernate.boot.model.relational.AuxiliaryDatabaseObject;
|
||||
import org.hibernate.boot.model.relational.Namespace;
|
||||
import org.hibernate.boot.model.relational.Sequence;
|
||||
import org.hibernate.boot.model.source.internal.annotations.AnnotationMetadataSourceProcessorImpl;
|
||||
import org.hibernate.boot.model.source.internal.hbm.EntityHierarchyBuilder;
|
||||
import org.hibernate.boot.model.source.internal.hbm.EntityHierarchySourceImpl;
|
||||
|
@ -33,6 +38,8 @@ import org.hibernate.boot.model.source.spi.MetadataSourceProcessor;
|
|||
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.AdditionalMappingContributions;
|
||||
import org.hibernate.boot.spi.AdditionalMappingContributor;
|
||||
import org.hibernate.boot.spi.BootstrapContext;
|
||||
import org.hibernate.boot.spi.MetadataBuildingOptions;
|
||||
import org.hibernate.boot.spi.MetadataContributor;
|
||||
|
@ -43,6 +50,8 @@ import org.hibernate.dialect.Dialect;
|
|||
import org.hibernate.engine.config.spi.ConfigurationService;
|
||||
import org.hibernate.engine.config.spi.StandardConverters;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.mapping.PersistentClass;
|
||||
import org.hibernate.mapping.Table;
|
||||
import org.hibernate.type.BasicType;
|
||||
import org.hibernate.type.BasicTypeRegistry;
|
||||
import org.hibernate.type.SqlTypes;
|
||||
|
@ -309,8 +318,138 @@ public class MetadataBuildingProcess {
|
|||
|
||||
processor.finishUp();
|
||||
|
||||
processAdditionalMappingContributions( options, metadataCollector, classLoaderService, rootMetadataBuildingContext );
|
||||
processAdditionalJaxbMappingProducer( options, metadataCollector, classLoaderService, rootMetadataBuildingContext, jandexView );
|
||||
|
||||
applyExtraQueryImports( managedResources, metadataCollector );
|
||||
|
||||
return metadataCollector.buildMetadataInstance( rootMetadataBuildingContext );
|
||||
}
|
||||
|
||||
private static void processAdditionalMappingContributions(MetadataBuildingOptions options, InFlightMetadataCollectorImpl metadataCollector, ClassLoaderService classLoaderService, MetadataBuildingContextRootImpl rootMetadataBuildingContext) {
|
||||
final EntityHierarchyBuilder hierarchyBuilder = new EntityHierarchyBuilder();
|
||||
final AdditionalMappingContributionsImpl contributions = new AdditionalMappingContributionsImpl(
|
||||
metadataCollector,
|
||||
options,
|
||||
rootMetadataBuildingContext,
|
||||
hierarchyBuilder
|
||||
);
|
||||
|
||||
final MappingBinder mappingBinder;
|
||||
if ( options.isXmlMappingEnabled() ) {
|
||||
mappingBinder = new MappingBinder(
|
||||
classLoaderService,
|
||||
new MappingBinder.Options() {
|
||||
@Override
|
||||
public boolean validateMappings() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean transformHbmMappings() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
else {
|
||||
mappingBinder = null;
|
||||
}
|
||||
|
||||
final Collection<AdditionalMappingContributor> additionalMappingContributors = classLoaderService.loadJavaServices( AdditionalMappingContributor.class );
|
||||
additionalMappingContributors.forEach( (contributor) -> {
|
||||
contributions.setCurrentContributor( contributor.getContributorName() );
|
||||
try {
|
||||
contributor.contribute(
|
||||
contributions,
|
||||
metadataCollector,
|
||||
mappingBinder,
|
||||
rootMetadataBuildingContext
|
||||
);
|
||||
}
|
||||
finally {
|
||||
contributions.setCurrentContributor( null );
|
||||
}
|
||||
} );
|
||||
|
||||
final ModelBinder binder = ModelBinder.prepare( rootMetadataBuildingContext );
|
||||
for ( EntityHierarchySourceImpl entityHierarchySource : hierarchyBuilder.buildHierarchies() ) {
|
||||
binder.bindEntityHierarchy( entityHierarchySource );
|
||||
}
|
||||
}
|
||||
|
||||
private static class AdditionalMappingContributionsImpl implements AdditionalMappingContributions {
|
||||
private final InFlightMetadataCollectorImpl metadataCollector;
|
||||
private final MetadataBuildingOptions options;
|
||||
private final MetadataBuildingContextRootImpl rootMetadataBuildingContext;
|
||||
private final EntityHierarchyBuilder hierarchyBuilder;
|
||||
private String currentContributor;
|
||||
|
||||
public AdditionalMappingContributionsImpl(
|
||||
InFlightMetadataCollectorImpl metadataCollector,
|
||||
MetadataBuildingOptions options,
|
||||
MetadataBuildingContextRootImpl rootMetadataBuildingContext,
|
||||
EntityHierarchyBuilder hierarchyBuilder) {
|
||||
this.metadataCollector = metadataCollector;
|
||||
this.options = options;
|
||||
this.rootMetadataBuildingContext = rootMetadataBuildingContext;
|
||||
this.hierarchyBuilder = hierarchyBuilder;
|
||||
}
|
||||
|
||||
public String getCurrentContributor() {
|
||||
return currentContributor;
|
||||
}
|
||||
|
||||
public void setCurrentContributor(String contributor) {
|
||||
this.currentContributor = contributor == null ? "orm" : contributor;
|
||||
}
|
||||
@Override
|
||||
public void contributeBinding(JaxbHbmHibernateMapping hbmJaxbBinding, Origin origin) {
|
||||
if ( ! options.isXmlMappingEnabled() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
hierarchyBuilder.indexMappingDocument( new MappingDocument(
|
||||
currentContributor,
|
||||
hbmJaxbBinding,
|
||||
origin,
|
||||
rootMetadataBuildingContext
|
||||
) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contributeEntity(PersistentClass entity) {
|
||||
metadataCollector.addEntityBinding( entity );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contributeTable(Table table) {
|
||||
final Namespace namespace = metadataCollector.getDatabase().locateNamespace(
|
||||
table.getCatalogIdentifier(),
|
||||
table.getSchemaIdentifier()
|
||||
);
|
||||
namespace.registerTable( table.getNameIdentifier(), table );
|
||||
metadataCollector.addTableNameBinding( table.getNameIdentifier(), table );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contributeSequence(Sequence sequence) {
|
||||
final Namespace namespace = metadataCollector.getDatabase().locateNamespace(
|
||||
sequence.getName().getCatalogName(),
|
||||
sequence.getName().getSchemaName()
|
||||
);
|
||||
namespace.registerSequence( sequence.getName().getSequenceName(), sequence );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contributeAuxiliaryDatabaseObject(AuxiliaryDatabaseObject auxiliaryDatabaseObject) {
|
||||
metadataCollector.addAuxiliaryDatabaseObject( auxiliaryDatabaseObject );
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
private static void processAdditionalJaxbMappingProducer(MetadataBuildingOptions options, InFlightMetadataCollectorImpl metadataCollector, ClassLoaderService classLoaderService, MetadataBuildingContextRootImpl rootMetadataBuildingContext, IndexView jandexView) {
|
||||
if ( options.isXmlMappingEnabled() ) {
|
||||
//noinspection deprecation
|
||||
final Iterable<AdditionalJaxbMappingProducer> producers = classLoaderService.loadJavaServices( AdditionalJaxbMappingProducer.class );
|
||||
if ( producers != null ) {
|
||||
final EntityHierarchyBuilder hierarchyBuilder = new EntityHierarchyBuilder();
|
||||
|
@ -348,10 +487,6 @@ public class MetadataBuildingProcess {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
applyExtraQueryImports( managedResources, metadataCollector );
|
||||
|
||||
return metadataCollector.buildMetadataInstance( rootMetadataBuildingContext );
|
||||
}
|
||||
|
||||
private static void applyExtraQueryImports(
|
||||
|
|
|
@ -11,9 +11,7 @@ import java.util.ArrayList;
|
|||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
@ -96,6 +94,18 @@ public class Namespace {
|
|||
return tables.get( logicalTableName );
|
||||
}
|
||||
|
||||
public void registerTable(Identifier logicalName, Table table) {
|
||||
final Table previous = tables.put( logicalName, table );
|
||||
if ( previous != null ) {
|
||||
log.debugf(
|
||||
"Replacing Table registration(%s) : %s -> %s",
|
||||
logicalName,
|
||||
previous,
|
||||
table
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a mapping Table instance.
|
||||
*
|
||||
|
@ -133,6 +143,13 @@ public class Namespace {
|
|||
return sequences.get( name );
|
||||
}
|
||||
|
||||
public void registerSequence(Identifier logicalName, Sequence sequence) {
|
||||
if ( sequences.containsKey( logicalName ) ) {
|
||||
throw new HibernateException( "Sequence was already registered with that name [" + logicalName.toString() + "]" );
|
||||
}
|
||||
sequences.put( logicalName, sequence );
|
||||
}
|
||||
|
||||
public Sequence createSequence(Identifier logicalName, Function<Identifier,Sequence> creator) {
|
||||
if ( sequences.containsKey( logicalName ) ) {
|
||||
throw new HibernateException( "Sequence was already registered with that name [" + logicalName.toString() + "]" );
|
||||
|
|
|
@ -16,8 +16,7 @@ import org.jboss.jandex.IndexView;
|
|||
/**
|
||||
* @author Steve Ebersole
|
||||
*
|
||||
* @deprecated Intended for Envers integration until we can migrate Envers
|
||||
* away from XML generation for building its model.
|
||||
* @deprecated Use {@linkplain AdditionalMappingContributor} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public interface AdditionalJaxbMappingProducer {
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* 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.hibernate.Incubating;
|
||||
import org.hibernate.boot.jaxb.Origin;
|
||||
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmHibernateMapping;
|
||||
import org.hibernate.boot.model.relational.AuxiliaryDatabaseObject;
|
||||
import org.hibernate.boot.model.relational.Sequence;
|
||||
import org.hibernate.mapping.PersistentClass;
|
||||
import org.hibernate.mapping.Table;
|
||||
|
||||
/**
|
||||
* Collector for contributions from {@linkplain AdditionalMappingContributor contributors}
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@Incubating
|
||||
public interface AdditionalMappingContributions {
|
||||
void contributeBinding(JaxbHbmHibernateMapping hbmJaxbBinding, Origin origin);
|
||||
void contributeEntity(PersistentClass entity);
|
||||
void contributeTable(Table table);
|
||||
void contributeSequence(Sequence sequence);
|
||||
void contributeAuxiliaryDatabaseObject(AuxiliaryDatabaseObject auxiliaryDatabaseObject);
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* 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.hibernate.Incubating;
|
||||
import org.hibernate.boot.jaxb.internal.MappingBinder;
|
||||
|
||||
/**
|
||||
* Contract allowing pluggable contributions of additional
|
||||
* mapping objects.
|
||||
*
|
||||
* Resolvable as a {@linkplain java.util.ServiceLoader Java service}.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@Incubating
|
||||
public interface AdditionalMappingContributor {
|
||||
default String getContributorName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Contribute the additional mappings
|
||||
*
|
||||
* @param contributions Collector of the contributions
|
||||
* @param metadata Current (live) metadata
|
||||
* @param jaxbBinder JAXB binding support for XML documents. May be {@code null}
|
||||
* if XML processing is {@linkplain MetadataBuildingOptions#isXmlMappingEnabled() disabled}
|
||||
* @param buildingContext Access to useful contextual details
|
||||
*/
|
||||
void contribute(
|
||||
AdditionalMappingContributions contributions,
|
||||
InFlightMetadataCollector metadata,
|
||||
MappingBinder jaxbBinder,
|
||||
MetadataBuildingContext buildingContext);
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* 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 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.spi.AdditionalMappingContributions;
|
||||
import org.hibernate.boot.spi.AdditionalMappingContributor;
|
||||
import org.hibernate.boot.spi.InFlightMetadataCollector;
|
||||
import org.hibernate.boot.spi.MetadataBuildingContext;
|
||||
import org.hibernate.boot.spi.MetadataBuildingOptions;
|
||||
import org.hibernate.envers.configuration.internal.MappingCollector;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
|
||||
import static org.hibernate.cfg.AvailableSettings.XML_MAPPING_ENABLED;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class AdditionalMappingContributorImpl implements AdditionalMappingContributor {
|
||||
@Override
|
||||
public String getContributorName() {
|
||||
return "envers";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contribute(
|
||||
AdditionalMappingContributions contributions,
|
||||
InFlightMetadataCollector metadata,
|
||||
MappingBinder jaxbBinder,
|
||||
MetadataBuildingContext buildingContext) {
|
||||
final 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;
|
||||
}
|
||||
|
||||
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 MappingCollector mappingCollector = new MappingCollector() {
|
||||
private final Origin origin = new Origin( SourceType.OTHER, "envers" );
|
||||
|
||||
@Override
|
||||
public void addDocument(JaxbHbmHibernateMapping mapping) {
|
||||
contributions.contributeBinding( mapping, origin );
|
||||
}
|
||||
};
|
||||
|
||||
enversService.initialize( metadata, mappingCollector );
|
||||
}
|
||||
}
|
|
@ -1,13 +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>.
|
||||
#
|
||||
#
|
||||
# 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>.
|
||||
#
|
||||
org.hibernate.envers.boot.internal.AdditionalJaxbMappingProducerImpl
|
|
@ -0,0 +1,7 @@
|
|||
#
|
||||
# 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.
|
||||
#
|
||||
org.hibernate.envers.boot.internal.AdditionalMappingContributorImpl
|
Loading…
Reference in New Issue