Skip to content

Commit

Permalink
Preliminary work on <entity/> XML overrides
Browse files Browse the repository at this point in the history
  • Loading branch information
sebersole committed Oct 20, 2023
1 parent 4bd4363 commit 2cea8e7
Show file tree
Hide file tree
Showing 6 changed files with 161 additions and 21 deletions.
7 changes: 3 additions & 4 deletions hibernate-models-orm/hibernate-models-orm.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,21 @@ dependencies {
implementation project( ":hibernate-models-common" )
implementation project( ":hibernate-models-source" )

implementation platform( libs.hibernatePlatform )
implementation libs.hibernateCore
implementation libs.jandex
implementation libs.byteBuddy
implementation libs.classmate

implementation libs.logging

compileOnly libs.loggingAnnotations
compileOnly libs.jpa
compileOnly libs.hibernateCore

annotationProcessor libs.loggingProcessor
annotationProcessor libs.logging
annotationProcessor libs.loggingAnnotations

testImplementation project( ":hibernate-models-testing" )
testImplementation libs.hibernateTesting
testImplementation testLibs.jpa
testImplementation libs.hibernateCore
testRuntimeOnly testLibs.log4j
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.hibernate.boot.jaxb.mapping.JaxbEntity;
import org.hibernate.boot.jaxb.mapping.JaxbEntityMappings;
import org.hibernate.boot.jaxb.mapping.JaxbMappedSuperclass;
import org.hibernate.boot.jaxb.mapping.ManagedType;
import org.hibernate.boot.jaxb.spi.BindableMappingDescriptor;
import org.hibernate.boot.jaxb.spi.Binding;
import org.hibernate.models.internal.CollectionHelper;
Expand Down Expand Up @@ -84,6 +85,24 @@ public static ProcessResult process(
return process( managedResources, explicitlyListedClasses, options, sourceModelBuildingContext, ormModelBuildingContext );
}

public static class OverrideTuple<M extends ManagedType> {
private final JaxbEntityMappings jaxbRoot;
private final M managedType;

public OverrideTuple(JaxbEntityMappings jaxbRoot, M managedType) {
this.jaxbRoot = jaxbRoot;
this.managedType = managedType;
}

public JaxbEntityMappings getJaxbRoot() {
return jaxbRoot;
}

public M getManagedType() {
return managedType;
}
}

public static ProcessResult process(
ManagedResources managedResources,
List<String> explicitlyListedClasses,
Expand All @@ -101,11 +120,11 @@ public static ProcessResult process(
// b. collect "incomplete" (override) mappings
// 3. apply XML overrides

final List<JaxbEntity> entityOverrides = new ArrayList<>();
final List<OverrideTuple<JaxbEntity>> entityOverrides = new ArrayList<>();
final List<JaxbEntity> entityCompletes = new ArrayList<>();
final List<JaxbMappedSuperclass> mappedSuperclassesOverrides = new ArrayList<>();
final List<OverrideTuple<JaxbMappedSuperclass>> mappedSuperclassesOverrides = new ArrayList<>();
final List<JaxbMappedSuperclass> mappedSuperclassesCompletes = new ArrayList<>();
final List<JaxbEmbeddable> embeddableOverrides = new ArrayList<>();
final List<OverrideTuple<JaxbEmbeddable>> embeddableOverrides = new ArrayList<>();
final List<JaxbEmbeddable> embeddableCompletes = new ArrayList<>();

final boolean xmlMappingsGloballyComplete = collectedXmlResources.getPersistenceUnitMetadata().areXmlMappingsComplete();
Expand All @@ -114,32 +133,32 @@ public static ProcessResult process(
processResultCollector.apply( jaxbRoot );

jaxbRoot.getEmbeddables().forEach( (embeddable) -> {
if ( xmlMappingsGloballyComplete || embeddable.isMetadataComplete() ) {
if ( xmlMappingsGloballyComplete || embeddable.isMetadataComplete() == Boolean.TRUE ) {
embeddableCompletes.add( embeddable );
XmlManagedTypeHelper.makeCompleteEmbeddableMapping( jaxbRoot, embeddable, collectedXmlResources.getPersistenceUnitMetadata(), sourceModelBuildingContext );
}
else {
embeddableOverrides.add( embeddable );
embeddableOverrides.add( new OverrideTuple<>( jaxbRoot, embeddable ) );
}
} );

jaxbRoot.getMappedSuperclasses().forEach( (mappedSuperclass) -> {
if ( xmlMappingsGloballyComplete || mappedSuperclass.isMetadataComplete() ) {
if ( xmlMappingsGloballyComplete || mappedSuperclass.isMetadataComplete() == Boolean.TRUE ) {
mappedSuperclassesCompletes.add( mappedSuperclass );
XmlManagedTypeHelper.makeCompleteMappedSuperclassMapping( jaxbRoot, mappedSuperclass, collectedXmlResources.getPersistenceUnitMetadata(), sourceModelBuildingContext );
}
else {
mappedSuperclassesOverrides.add( mappedSuperclass );
mappedSuperclassesOverrides.add( new OverrideTuple<>( jaxbRoot, mappedSuperclass ) );
}
});

jaxbRoot.getEntities().forEach( (entity) -> {
if ( xmlMappingsGloballyComplete || entity.isMetadataComplete() ) {
if ( xmlMappingsGloballyComplete || entity.isMetadataComplete() == Boolean.TRUE ) {
entityCompletes.add( entity );
XmlManagedTypeHelper.makeCompleteEntityMapping( jaxbRoot, entity, collectedXmlResources.getPersistenceUnitMetadata(), sourceModelBuildingContext );
}
else {
entityOverrides.add( entity );
entityOverrides.add( new OverrideTuple<>( jaxbRoot, entity ) );
}
} );
} );
Expand Down Expand Up @@ -181,9 +200,9 @@ public static ProcessResult process(
mappingBuildingContext
);

XmlManagedTypeHelper.applyEntityOverrides( allEntities, entityOverrides );
XmlManagedTypeHelper.applyMappedSuperclassOverrides( mappedSuperClasses, mappedSuperclassesOverrides );
XmlManagedTypeHelper.applyEmbeddableOverrides( embeddables, embeddableOverrides );
XmlManagedTypeHelper.applyEntityOverrides( allEntities, entityOverrides, sourceModelBuildingContext );
XmlManagedTypeHelper.applyMappedSuperclassOverrides( mappedSuperClasses, mappedSuperclassesOverrides, sourceModelBuildingContext );
XmlManagedTypeHelper.applyEmbeddableOverrides( embeddables, embeddableOverrides, sourceModelBuildingContext );

final Set<EntityHierarchy> entityHierarchies = createEntityHierarchies(
rootEntities,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.hibernate.boot.jaxb.mapping.ManagedType;
import org.hibernate.models.internal.CollectionHelper;
import org.hibernate.models.internal.StringHelper;
import org.hibernate.models.orm.spi.Processor;
import org.hibernate.models.orm.xml.spi.PersistenceUnitMetadata;
import org.hibernate.models.source.internal.MutableClassDetails;
import org.hibernate.models.source.internal.MutableMemberDetails;
Expand Down Expand Up @@ -288,19 +289,31 @@ public static void makeCompleteEmbeddableMapping(

public static void applyMappedSuperclassOverrides(
Map<String, ClassDetails> mappedSuperClasses,
List<JaxbMappedSuperclass> mappedSuperclassesOverrides) {

List<Processor.OverrideTuple<JaxbMappedSuperclass>> mappedSuperclassesOverrides,
SourceModelBuildingContext sourceModelBuildingContext) {
throw new UnsupportedOperationException( "<mapped-superclass/> override support not yet implemented" );
}

public static void applyEntityOverrides(
Map<String, ClassDetails> allEntities,
List<JaxbEntity> entityOverrides) {
List<Processor.OverrideTuple<JaxbEntity>> entityOverrides,
SourceModelBuildingContext sourceModelBuildingContext) {
entityOverrides.forEach( (overrideTuple) -> {
final JaxbEntityMappings jaxbRoot = overrideTuple.getJaxbRoot();
final JaxbEntity jaxbEntity = overrideTuple.getManagedType();
final String className = determineClassName( jaxbRoot, jaxbEntity );
final MutableClassDetails classDetails = (MutableClassDetails) sourceModelBuildingContext
.getClassDetailsRegistry()
.resolveClassDetails( className );
} );

throw new UnsupportedOperationException( "<entity/> override support not yet implemented" );
}

public static void applyEmbeddableOverrides(
Map<String, ClassDetails> embeddables,
List<JaxbEmbeddable> embeddableOverrides) {

List<Processor.OverrideTuple<JaxbEmbeddable>> embeddableOverrides,
SourceModelBuildingContext sourceModelBuildingContext) {
throw new UnsupportedOperationException( "<embeddable/> override support not yet implemented" );
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* SPDX-License-Identifier: Apache-2.0
* Copyright: Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.models.orm.xml.override;

import org.hibernate.models.orm.internal.ManagedResourcesImpl;
import org.hibernate.models.orm.spi.AttributeMetadata;
import org.hibernate.models.orm.spi.EntityHierarchy;
import org.hibernate.models.orm.spi.EntityTypeMetadata;
import org.hibernate.models.orm.spi.ManagedResources;
import org.hibernate.models.orm.spi.ProcessResult;
import org.hibernate.models.orm.spi.Processor;
import org.hibernate.models.orm.xml.SimpleEntity;
import org.hibernate.models.source.SourceModelTestHelper;
import org.hibernate.models.source.internal.SourceModelBuildingContextImpl;
import org.hibernate.models.source.spi.AnnotationUsage;

import org.hibernate.testing.orm.junit.FailureExpected;
import org.junit.jupiter.api.Test;

import org.jboss.jandex.Index;

import jakarta.persistence.Basic;
import jakarta.persistence.Column;
import jakarta.persistence.Id;

import static org.assertj.core.api.Assertions.assertThat;
import static org.hibernate.models.internal.SimpleClassLoading.SIMPLE_CLASS_LOADING;

/**
* @author Steve Ebersole
*/
public class SimpleOverrideXmlTests {
@Test
@FailureExpected
void testSimpleCompleteEntity() {

final ManagedResourcesImpl.Builder managedResourcesBuilder = new ManagedResourcesImpl.Builder();
managedResourcesBuilder.addXmlMappings( "mappings/override/simple-override.xml" );
final ManagedResources managedResources = managedResourcesBuilder.build();

final Index jandexIndex = SourceModelTestHelper.buildJandexIndex(
SIMPLE_CLASS_LOADING,
SimpleEntity.class
);
final SourceModelBuildingContextImpl buildingContext = SourceModelTestHelper.createBuildingContext(
jandexIndex,
SIMPLE_CLASS_LOADING
);

final ProcessResult processResult = Processor.process(
managedResources,
null,
new Processor.Options() {
@Override
public boolean areGeneratorsGlobal() {
return false;
}

@Override
public boolean shouldIgnoreUnlistedClasses() {
return false;
}
},
buildingContext
);

assertThat( processResult.getEntityHierarchies() ).hasSize( 1 );

final EntityHierarchy hierarchy = processResult.getEntityHierarchies().iterator().next();
final EntityTypeMetadata root = hierarchy.getRoot();
assertThat( root.getClassDetails().getClassName() ).isEqualTo( SimpleEntity.class.getName() );
assertThat( root.getNumberOfAttributes() ).isEqualTo( 2 );

final AttributeMetadata idAttribute = root.findAttribute( "id" );
assertThat( idAttribute.getNature() ).isEqualTo( AttributeMetadata.AttributeNature.BASIC );
assertThat( idAttribute.getMember().getAnnotationUsage( Id.class ) ).isNotNull();

final AttributeMetadata nameAttribute = root.findAttribute( "name" );
assertThat( nameAttribute.getNature() ).isEqualTo( AttributeMetadata.AttributeNature.BASIC );
assertThat( nameAttribute.getMember().getAnnotationUsage( Basic.class ) ).isNotNull();
final AnnotationUsage<Column> nameColumnAnn = nameAttribute.getMember().getAnnotationUsage( Column.class );
assertThat( nameColumnAnn ).isNotNull();
assertThat( nameColumnAnn.<String>getAttributeValue( "name" ) ).isEqualTo( "description" );
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!--
~ Hibernate, Relational Persistence for Idiomatic Java
~
~ SPDX-License-Identifier: Apache-2.0
~ Copyright: Red Hat Inc. and Hibernate Authors
-->
<entity-mappings xmlns="http://www.hibernate.org/xsd/orm/mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="3.1">

<entity class="org.hibernate.models.orm.xml.SimpleEntity" access="FIELD">
<attributes>
<basic name="name">
<column name="description"/>
</basic>
</attributes>
</entity>

</entity-mappings>
1 change: 1 addition & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ dependencyResolutionManagement {

def hibernateVersion = version "hibernateOrm", "6.3.0.Final"
library( "hibernateCore", "org.hibernate.orm", "hibernate-core" ).versionRef( hibernateVersion )
library( "hibernateTesting", "org.hibernate.orm", "hibernate-testing" ).versionRef( hibernateVersion )
library( "hibernatePlatform", "org.hibernate.orm", "hibernate-platform" ).versionRef( hibernateVersion )

def jacksonVersion = version "jackson", "2.14.1"
Expand Down

0 comments on commit 2cea8e7

Please sign in to comment.