Skip to content

Commit

Permalink
Continue support for XML complete mappings - inheritance
Browse files Browse the repository at this point in the history
  • Loading branch information
sebersole committed Oct 19, 2023
1 parent deeb219 commit 25dce1e
Show file tree
Hide file tree
Showing 9 changed files with 263 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@
import org.hibernate.boot.jaxb.mapping.JaxbColumnType;
import org.hibernate.boot.jaxb.mapping.JaxbConfigurationParameter;
import org.hibernate.boot.jaxb.mapping.JaxbConvert;
import org.hibernate.boot.jaxb.mapping.JaxbEmbeddedId;
import org.hibernate.boot.jaxb.mapping.JaxbGeneratedValue;
import org.hibernate.boot.jaxb.mapping.JaxbId;
import org.hibernate.boot.jaxb.mapping.JaxbLob;
import org.hibernate.boot.jaxb.mapping.JaxbNationalized;
import org.hibernate.boot.jaxb.mapping.JaxbNaturalId;
Expand Down Expand Up @@ -55,16 +57,19 @@
import jakarta.persistence.Basic;
import jakarta.persistence.Column;
import jakarta.persistence.Convert;
import jakarta.persistence.EmbeddedId;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.Lob;
import jakarta.persistence.SequenceGenerator;
import jakarta.persistence.Table;
import jakarta.persistence.TableGenerator;
import jakarta.persistence.Temporal;
import jakarta.persistence.TemporalType;

import static jakarta.persistence.FetchType.EAGER;
import static java.util.Collections.emptyList;
import static org.hibernate.internal.util.NullnessHelper.coalesce;
import static org.hibernate.models.internal.StringHelper.nullIfEmpty;
Expand All @@ -86,6 +91,16 @@ public static void applyBasic(
annotationUsage.setAttributeValue( "optional", jaxbBasic.isOptional() );
}

public static void applyBasic(
JaxbId jaxbId,
MutableMemberDetails memberDetails,
SourceModelBuildingContext sourceModelBuildingContext) {
final DynamicAnnotationUsage<Basic> annotationUsage = new DynamicAnnotationUsage<>( Basic.class, memberDetails );
memberDetails.addAnnotationUsage( annotationUsage );
annotationUsage.setAttributeValue( "fetch", EAGER );
annotationUsage.setAttributeValue( "optional", false );
}

public static void applyAccess(
AccessType accessType,
MutableMemberDetails memberDetails,
Expand Down Expand Up @@ -496,4 +511,32 @@ public static void applyNaturalIdCache(
final JaxbCaching jaxbCaching = jaxbNaturalId.getCache();
annotationUsage.setAttributeValue( "region", jaxbCaching.getRegion() );
}

public static void applyId(
JaxbId jaxbId,
MutableMemberDetails memberDetails,
SourceModelBuildingContext sourceModelBuildingContext) {
if ( jaxbId == null ) {
return;
}
final DynamicAnnotationUsage<Id> annotationUsage = new DynamicAnnotationUsage<>(
Id.class,
memberDetails
);
memberDetails.addAnnotationUsage( annotationUsage );
}

public static void applyEmbeddedId(
JaxbEmbeddedId jaxbEmbeddedId,
MutableMemberDetails memberDetails,
SourceModelBuildingContext sourceModelBuildingContext) {
if ( jaxbEmbeddedId == null ) {
return;
}
final DynamicAnnotationUsage<EmbeddedId> annotationUsage = new DynamicAnnotationUsage<>(
EmbeddedId.class,
memberDetails
);
memberDetails.addAnnotationUsage( annotationUsage );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.hibernate.models.orm.xml.spi.PersistenceUnitMetadata;
import org.hibernate.models.source.internal.MutableClassDetails;
import org.hibernate.models.source.internal.MutableMemberDetails;
import org.hibernate.models.source.internal.SourceModelLogging;
import org.hibernate.models.source.internal.dynamic.DynamicAnnotationUsage;
import org.hibernate.models.source.internal.dynamic.DynamicClassDetails;
import org.hibernate.models.source.spi.ClassDetails;
Expand All @@ -31,6 +32,7 @@
import jakarta.persistence.AccessType;
import jakarta.persistence.Embeddable;
import jakarta.persistence.Entity;
import jakarta.persistence.Inheritance;

import static org.hibernate.internal.util.NullnessHelper.coalesce;

Expand Down Expand Up @@ -109,6 +111,8 @@ public static void makeCompleteEntityMapping(
entityAnn.setAttributeValue( "name", jaxbEntity.getName() );
classDetails.addAnnotationUsage( entityAnn );

applyInheritance( jaxbEntity, classDetails, sourceModelBuildingContext );

if ( jaxbEntity.getTable() != null ) {
XmlAnnotationHelper.applyTable( jaxbEntity.getTable(), classDetails, persistenceUnitMetadata );
}
Expand All @@ -132,14 +136,33 @@ public static void makeCompleteEntityMapping(
// todo : secondary-tables
}

private static void applyInheritance(
JaxbEntity jaxbEntity,
MutableClassDetails classDetails,
SourceModelBuildingContext sourceModelBuildingContext) {
if ( jaxbEntity.getInheritance() == null ) {
return;
}

final DynamicAnnotationUsage<Inheritance> annotationUsage = new DynamicAnnotationUsage<>(
Inheritance.class,
classDetails
);
classDetails.addAnnotationUsage( annotationUsage );
annotationUsage.setAttributeValue( "strategy", jaxbEntity.getInheritance().getStrategy() );
}

private static void handleIdMappings(
JaxbAttributes attributes,
AccessType classAccessType,
MutableClassDetails classDetails,
SourceModelBuildingContext sourceModelBuildingContext) {
if ( CollectionHelper.isNotEmpty( attributes.getId() ) ) {
for ( int i = 0; i < attributes.getId().size(); i++ ) {
final JaxbId jaxbId = attributes.getId().get( i );
final List<JaxbId> jaxbIds = attributes.getId();
final JaxbEmbeddedId jaxbEmbeddedId = attributes.getEmbeddedId();

if ( CollectionHelper.isNotEmpty( jaxbIds ) ) {
for ( int i = 0; i < jaxbIds.size(); i++ ) {
final JaxbId jaxbId = jaxbIds.get( i );
final AccessType accessType = coalesce( jaxbId.getAccess(), classAccessType );
final MutableMemberDetails memberDetails = XmlAttributeHelper.findAttributeMember(
jaxbId.getName(),
Expand All @@ -148,6 +171,8 @@ private static void handleIdMappings(
sourceModelBuildingContext
);

XmlAnnotationHelper.applyId( jaxbId, memberDetails, sourceModelBuildingContext );
XmlAnnotationHelper.applyBasic( jaxbId, memberDetails, sourceModelBuildingContext );
XmlAttributeHelper.applyCommonAttributeAnnotations(
jaxbId,
memberDetails,
Expand Down Expand Up @@ -201,9 +226,7 @@ private static void handleIdMappings(
// todo : unsaved-value?
}
}
else {
final JaxbEmbeddedId jaxbEmbeddedId = attributes.getEmbeddedId();
assert jaxbEmbeddedId != null;
else if ( jaxbEmbeddedId != null ) {
final AccessType accessType = coalesce( jaxbEmbeddedId.getAccess(), classAccessType );
final MutableMemberDetails memberDetails = XmlAttributeHelper.findAttributeMember(
jaxbEmbeddedId.getName(),
Expand All @@ -212,6 +235,7 @@ private static void handleIdMappings(
sourceModelBuildingContext
);

XmlAnnotationHelper.applyEmbeddedId( jaxbEmbeddedId, memberDetails, sourceModelBuildingContext );
XmlAttributeHelper.applyCommonAttributeAnnotations(
jaxbEmbeddedId,
memberDetails,
Expand All @@ -225,6 +249,12 @@ private static void handleIdMappings(
sourceModelBuildingContext
);
}
else {
SourceModelLogging.SOURCE_MODEL_LOGGER.debugf(
"Identifiable type [%s] contained no <id/> nor <embedded-id/>",
classDetails.getName()
);
}
}

public static void makeCompleteEmbeddableMapping(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* 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.complete;

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.source.SourceModelTestHelper;
import org.hibernate.models.source.internal.SourceModelBuildingContextImpl;

import org.junit.jupiter.api.Test;

import org.jboss.jandex.Index;

import jakarta.persistence.Id;

import static jakarta.persistence.InheritanceType.JOINED;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hibernate.models.internal.SimpleClassLoading.SIMPLE_CLASS_LOADING;

/**
* @author Steve Ebersole
*/
public class CompleteXmlInheritanceTests {
@Test
void testIt() {

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

final Index jandexIndex = SourceModelTestHelper.buildJandexIndex(
SIMPLE_CLASS_LOADING,
Root.class,
Sub.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();
assertThat( hierarchy.getInheritanceType() ).isEqualTo( JOINED );

final EntityTypeMetadata rootMetadata = hierarchy.getRoot();
assertThat( rootMetadata.getClassDetails().getClassName() ).isEqualTo( Root.class.getName() );
final AttributeMetadata idAttr = rootMetadata.findAttribute( "id" );
assertThat( idAttr.getMember().getAnnotationUsage( Id.class ) ).isNotNull();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
import org.jboss.jandex.Index;

import jakarta.persistence.AccessType;
import jakarta.persistence.Basic;
import jakarta.persistence.Embedded;
import jakarta.persistence.Id;

import static org.assertj.core.api.Assertions.assertThat;
import static org.hibernate.models.internal.SimpleClassLoading.SIMPLE_CLASS_LOADING;
Expand Down Expand Up @@ -75,8 +78,11 @@ public boolean shouldIgnoreUnlistedClasses() {

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

final AttributeMetadata nameAttribute = personMetadata.findAttribute( "name" );
assertThat( nameAttribute.getNature() ).isEqualTo( EMBEDDED );
assertThat( nameAttribute.getMember().getAnnotationUsage( Embedded.class ) ).isNotNull();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* 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.complete;

/**
* @author Steve Ebersole
*/
public class Root {
private Integer id;
private String name;

protected Root() {
// for Hibernate use
}

public Root(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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@

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;
Expand Down Expand Up @@ -73,12 +75,15 @@ public boolean shouldIgnoreUnlistedClasses() {

final AttributeMetadata idAttribute = root.findAttribute( "id" );
assertThat( idAttribute.getNature() ).isEqualTo( AttributeMetadata.AttributeNature.BASIC );
assertThat( idAttribute.getMember().getAnnotationUsage( Basic.class ) ).isNotNull();
assertThat( idAttribute.getMember().getAnnotationUsage( Id.class ) ).isNotNull();
final AnnotationUsage<Column> idColumnAnn = idAttribute.getMember().getAnnotationUsage( Column.class );
assertThat( idColumnAnn ).isNotNull();
assertThat( idColumnAnn.<String>getAttributeValue( "name" ) ).isEqualTo( "pk" );

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" );
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* 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.complete;

/**
* @author Steve Ebersole
*/
public class Sub extends Root {
private String subName;

protected Sub() {
// for Hibernate use
}

public Sub(Integer id, String name, String subName) {
super( id, name );
this.subName = subName;
}

public String getSubName() {
return subName;
}

public void setSubName(String subName) {
this.subName = subName;
}
}
Loading

0 comments on commit 25dce1e

Please sign in to comment.