HHH-16115 - Develop an intermediate metamodel binding model

HHH-16116 - Bind intermediate metamodel into PersistentClass, et al.
This commit is contained in:
Steve Ebersole 2023-03-05 12:54:45 -06:00
parent 8e8bc00434
commit ff6d79ca63
12 changed files with 212 additions and 23 deletions

View File

@ -23,6 +23,7 @@ import org.hibernate.Internal;
import org.hibernate.boot.archive.spi.InputStreamAccess;
import org.hibernate.boot.internal.MetadataBuilderImpl;
import org.hibernate.boot.jaxb.internal.XmlSources;
import org.hibernate.boot.jaxb.spi.BindableMappingDescriptor;
import org.hibernate.boot.jaxb.spi.Binding;
import org.hibernate.boot.jaxb.spi.XmlSource;
import org.hibernate.boot.registry.BootstrapServiceRegistry;
@ -64,7 +65,7 @@ public class MetadataSources implements Serializable {
private XmlMappingBinderAccess xmlMappingBinderAccess;
private List<Binding<?>> xmlBindings;
private List<Binding<BindableMappingDescriptor>> xmlBindings;
private LinkedHashSet<Class<?>> annotatedClasses;
private LinkedHashSet<String> annotatedClassNames;
private LinkedHashSet<String> annotatedPackages;
@ -120,7 +121,7 @@ public class MetadataSources implements Serializable {
return xmlMappingBinderAccess;
}
public List<Binding<?>> getXmlBindings() {
public List<Binding<BindableMappingDescriptor>> getXmlBindings() {
return xmlBindings == null ? Collections.emptyList() : xmlBindings;
}
@ -371,7 +372,8 @@ public class MetadataSources implements Serializable {
* @return this (for method chaining purposes)
*/
public MetadataSources addXmlBinding(Binding<?> binding) {
getXmlBindingsForWrite().add( binding );
//noinspection unchecked
getXmlBindingsForWrite().add( (Binding<BindableMappingDescriptor>) binding );
return this;
}
@ -547,7 +549,7 @@ public class MetadataSources implements Serializable {
return this;
}
private List<Binding<?>> getXmlBindingsForWrite() {
private List<Binding<BindableMappingDescriptor>> getXmlBindingsForWrite() {
if ( xmlBindings == null ) {
xmlBindings = new ArrayList<>();
}

View File

@ -513,6 +513,10 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector,
return this;
}
public AttributeConverterManager getAttributeConverterManager() {
return attributeConverterManager;
}
@Override
public void addAttributeConverter(Class<? extends AttributeConverter<?,?>> converterClass) {
attributeConverterManager.addConverter(

View File

@ -46,6 +46,13 @@ public class AttributeConverterManager implements ConverterAutoApplyHandler {
private Map<Class<?>, ConverterDescriptor> attributeConverterDescriptorsByClass;
private Map<Class<?>, RegisteredConversion> registeredConversionsByDomainType;
public RegisteredConversion findRegisteredConversion(Class<?> domainType) {
if ( registeredConversionsByDomainType == null ) {
return null;
}
return registeredConversionsByDomainType.get( domainType );
}
public void addConverter(ConverterDescriptor descriptor) {
if ( log.isTraceEnabled() ) {
log.tracef( "Starting AttributeConverterManager#addConverter : `%s`",

View File

@ -317,7 +317,7 @@ public class InheritanceState {
//add MappedSuperclass if not already there
mappedSuperclass = buildingContext.getMetadataCollector().getMappedSuperclass( type );
if ( mappedSuperclass == null ) {
mappedSuperclass = new org.hibernate.mapping.MappedSuperclass( parentSuperclass, superEntity );
mappedSuperclass = new org.hibernate.mapping.MappedSuperclass( parentSuperclass, superEntity, persistentClass.getImplicitTable() );
mappedSuperclass.setMappedClass( type );
buildingContext.getMetadataCollector().addMappedSuperclass( type, mappedSuperclass );
}

View File

@ -242,6 +242,12 @@ public class Identifier implements Comparable<Identifier> {
return getCanonicalName().equals( that.getCanonicalName() );
}
public boolean matches(String name) {
return isQuoted()
? text.equals( name )
: text.equalsIgnoreCase( name );
}
@Override
public int hashCode() {
return isQuoted ? text.hashCode() : text.toLowerCase( Locale.ENGLISH ).hashCode();

View File

@ -17,20 +17,23 @@ import java.util.Set;
import org.hibernate.Internal;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.jaxb.spi.BindableMappingDescriptor;
import org.hibernate.boot.jaxb.spi.Binding;
import org.hibernate.boot.model.convert.spi.ConverterDescriptor;
import org.hibernate.boot.model.process.spi.ManagedResources;
import org.hibernate.boot.spi.BootstrapContext;
import jakarta.persistence.AttributeConverter;
/**
* @author Steve Ebersole
*/
public class ManagedResourcesImpl implements ManagedResources {
private Map<Class, ConverterDescriptor> attributeConverterDescriptorMap = new HashMap<>();
private Set<Class> annotatedClassReferences = new LinkedHashSet<>();
private Set<String> annotatedClassNames = new LinkedHashSet<>();
private Set<String> annotatedPackageNames = new LinkedHashSet<>();
private List<Binding> mappingFileBindings = new ArrayList<>();
private final Map<Class<? extends AttributeConverter>, ConverterDescriptor> attributeConverterDescriptorMap = new HashMap<>();
private final Set<Class<?>> annotatedClassReferences = new LinkedHashSet<>();
private final Set<String> annotatedClassNames = new LinkedHashSet<>();
private final Set<String> annotatedPackageNames = new LinkedHashSet<>();
private final List<Binding<BindableMappingDescriptor>> mappingFileBindings = new ArrayList<>();
private Map<String, Class<?>> extraQueryImports;
public static ManagedResourcesImpl baseline(MetadataSources sources, BootstrapContext bootstrapContext) {
@ -44,7 +47,7 @@ public class ManagedResourcesImpl implements ManagedResources {
return impl;
}
private ManagedResourcesImpl() {
public ManagedResourcesImpl() {
}
@Override
@ -53,7 +56,7 @@ public class ManagedResourcesImpl implements ManagedResources {
}
@Override
public Collection<Class> getAnnotatedClassReferences() {
public Collection<Class<?>> getAnnotatedClassReferences() {
return Collections.unmodifiableSet( annotatedClassReferences );
}
@ -68,7 +71,7 @@ public class ManagedResourcesImpl implements ManagedResources {
}
@Override
public Collection<Binding> getXmlMappingBindings() {
public Collection<Binding<BindableMappingDescriptor>> getXmlMappingBindings() {
return Collections.unmodifiableList( mappingFileBindings );
}
@ -87,7 +90,7 @@ public class ManagedResourcesImpl implements ManagedResources {
}
@Internal
public void addAnnotatedClassReference(Class annotatedClassReference) {
public void addAnnotatedClassReference(Class<?> annotatedClassReference) {
annotatedClassReferences.add( annotatedClassReference );
}
@ -102,7 +105,7 @@ public class ManagedResourcesImpl implements ManagedResources {
}
@Internal
public void addXmlBinding(Binding binding) {
public void addXmlBinding(Binding<BindableMappingDescriptor> binding) {
mappingFileBindings.add( binding );
}
}

View File

@ -9,6 +9,7 @@ package org.hibernate.boot.model.process.spi;
import java.util.Collection;
import java.util.Map;
import org.hibernate.boot.jaxb.spi.BindableMappingDescriptor;
import org.hibernate.boot.jaxb.spi.Binding;
import org.hibernate.boot.model.convert.spi.ConverterDescriptor;
@ -40,7 +41,7 @@ public interface ManagedResources {
*
* @return The list of entity/component classes known by Class reference.
*/
Collection<Class> getAnnotatedClassReferences();
Collection<Class<?>> getAnnotatedClassReferences();
/**
* Informational access to any entity and component classes in the user domain model known by name.
@ -64,7 +65,7 @@ public interface ManagedResources {
*
* @return The list of bindings for all known XML mapping files.
*/
Collection<Binding> getXmlMappingBindings();
Collection<Binding<BindableMappingDescriptor>> getXmlMappingBindings();
Map<String,Class<?>> getExtraQueryImports();
}

View File

@ -12,6 +12,7 @@ import java.util.List;
import java.util.Set;
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmHibernateMapping;
import org.hibernate.boot.jaxb.spi.BindableMappingDescriptor;
import org.hibernate.boot.jaxb.spi.Binding;
import org.hibernate.boot.model.process.spi.ManagedResources;
import org.hibernate.boot.model.source.spi.MetadataSourceProcessor;
@ -40,16 +41,15 @@ public class HbmMetadataSourceProcessorImpl implements MetadataSourceProcessor {
this( managedResources.getXmlMappingBindings(), rootBuildingContext );
}
@SuppressWarnings("unchecked")
public HbmMetadataSourceProcessorImpl(
Collection<Binding> xmlBindings,
Collection<Binding<BindableMappingDescriptor>> xmlBindings,
MetadataBuildingContext rootBuildingContext) {
this.rootBuildingContext = rootBuildingContext;
final EntityHierarchyBuilder hierarchyBuilder = new EntityHierarchyBuilder();
this.mappingDocuments = new ArrayList<>();
for ( Binding xmlBinding : xmlBindings ) {
for ( Binding<BindableMappingDescriptor> xmlBinding : xmlBindings ) {
if ( !(xmlBinding.getRoot() instanceof JaxbHbmHibernateMapping) ) {
continue;
}

View File

@ -0,0 +1,26 @@
/*
* 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.mapping;
import java.util.List;
/**
* Commonality between {@link PersistentClass} and {@link MappedSuperclass},
* what JPA calls an {@linkplain jakarta.persistence.metamodel.IdentifiableType identifiable type}.
*
* @author Steve Ebersole
*/
public interface IdentifiableTypeClass extends TableContainer {
IdentifiableTypeClass getSuperType();
List<IdentifiableTypeClass> getSubTypes();
List<Property> getDeclaredProperties();
Table getImplicitTable();
void applyProperty(Property property);
}

View File

@ -17,18 +17,23 @@ import java.util.List;
*
* @author Emmanuel Bernard
*/
public class MappedSuperclass {
public class MappedSuperclass implements IdentifiableTypeClass {
private final MappedSuperclass superMappedSuperclass;
private final PersistentClass superPersistentClass;
private final List<Property> declaredProperties;
private final Table implicitTable;
private Class<?> mappedClass;
private Property identifierProperty;
private Property version;
private Component identifierMapper;
public MappedSuperclass(MappedSuperclass superMappedSuperclass, PersistentClass superPersistentClass) {
public MappedSuperclass(
MappedSuperclass superMappedSuperclass,
PersistentClass superPersistentClass,
Table implicitTable) {
this.superMappedSuperclass = superMappedSuperclass;
this.superPersistentClass = superPersistentClass;
this.implicitTable = implicitTable;
this.declaredProperties = new ArrayList<>();
}
@ -205,4 +210,49 @@ public class MappedSuperclass {
public void prepareForMappingModel() {
declaredProperties.sort( Comparator.comparing( Property::getName ) );
}
@Override
public Table findTable(String name) {
return null;
}
@Override
public Table getTable(String name) {
return null;
}
@Override
public Join findSecondaryTable(String name) {
return null;
}
@Override
public Join getSecondaryTable(String name) {
return null;
}
@Override
public IdentifiableTypeClass getSuperType() {
if ( superPersistentClass != null ) {
return superPersistentClass;
}
return superMappedSuperclass;
}
@Override
public List<IdentifiableTypeClass> getSubTypes() {
throw new UnsupportedOperationException( "Not implemented yet" );
}
@Override
public Table getImplicitTable() {
return implicitTable;
}
@Override
public void applyProperty(Property property) {
assert property.getValue().getTable() != null;
assert property.getValue().getTable().equals( getImplicitTable() );
addDeclaredProperty( property );
}
}

View File

@ -53,7 +53,7 @@ import static org.hibernate.sql.Template.collectColumnNames;
*
* @author Gavin King
*/
public abstract class PersistentClass implements AttributeContainer, Serializable, Filterable, MetaAttributable, Contributable {
public abstract class PersistentClass implements IdentifiableTypeClass, AttributeContainer, Filterable, MetaAttributable, Contributable, Serializable {
private static final Alias PK_ALIAS = new Alias( 15, "PK" );
@ -1328,4 +1328,75 @@ public abstract class PersistentClass implements AttributeContainer, Serializabl
public List<CheckConstraint> getCheckConstraints() {
return checkConstraints;
}
public Table getImplicitTable() {
return getTable();
}
@Override
public Table findTable(String name) {
if ( getTable().getName().equals( name ) ) {
return getTable();
}
final Join secondaryTable = findSecondaryTable( name );
if ( secondaryTable != null ) {
return secondaryTable.getTable();
}
return null;
}
@Override
public Table getTable(String name) {
final Table table = findTable( name );
if ( table == null ) {
throw new MappingException( "Could not locate Table : " + name );
}
return table;
}
@Override
public Join findSecondaryTable(String name) {
for ( int i = 0; i < joins.size(); i++ ) {
final Join join = joins.get( i );
if ( join.getTable().getNameIdentifier().matches( name ) ) {
return join;
}
}
return null;
}
@Override
public Join getSecondaryTable(String name) {
final Join secondaryTable = findSecondaryTable( name );
if ( secondaryTable == null ) {
throw new MappingException( "Could not locate secondary Table : " + name );
}
return secondaryTable;
}
@Override
public IdentifiableTypeClass getSuperType() {
final PersistentClass superPersistentClass = getSuperclass();
if ( superPersistentClass != null ) {
return superPersistentClass;
}
return superMappedSuperclass;
}
@Override
public List<IdentifiableTypeClass> getSubTypes() {
throw new UnsupportedOperationException( "Not implemented yet" );
}
@Override
public void applyProperty(Property property) {
if ( property.getValue().getTable().equals( getImplicitTable() ) ) {
addProperty( property );
}
else {
final Join secondaryTable = getSecondaryTable( property.getValue().getTable().getName() );
secondaryTable.addProperty( property );
}
}
}

View File

@ -0,0 +1,19 @@
/*
* 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.mapping;
/**
* Container for Table and Join reference
*
* @author Steve Ebersole
*/
public interface TableContainer {
Table findTable(String name);
Table getTable(String name);
Join findSecondaryTable(String name);
Join getSecondaryTable(String name);
}