HHH-18387 - Support implied mapped-superclass in hbm.xml transformation

This commit is contained in:
Steve Ebersole 2024-07-16 08:01:54 -05:00
parent dd6986a26d
commit cb538f9d28
9 changed files with 203 additions and 18 deletions

View File

@ -1398,14 +1398,15 @@ public class HbmXmlTransformer {
); );
} }
else if ( hbmAttributeMapping instanceof JaxbHbmOneToOneType hbmOneToOne ) { else if ( hbmAttributeMapping instanceof JaxbHbmOneToOneType hbmOneToOne ) {
transferOneToOne( hbmOneToOne, attributes ); final PropertyInfo propertyInfo = managedTypeInfo.propertyInfoMap().get( hbmOneToOne.getName() );
transferOneToOne( hbmOneToOne, propertyInfo, attributes );
} }
else if ( hbmAttributeMapping instanceof JaxbHbmManyToOneType hbmManyToOne ) { else if ( hbmAttributeMapping instanceof JaxbHbmManyToOneType hbmManyToOne ) {
final PropertyInfo propertyInfo = managedTypeInfo.propertyInfoMap().get( hbmManyToOne.getName() ); transferManyToOne( managedTypeInfo, attributes, hbmManyToOne );
attributes.getManyToOneAttributes().add( transformManyToOne( hbmManyToOne, propertyInfo ) );
} }
else if ( hbmAttributeMapping instanceof JaxbHbmAnyAssociationType any ) { else if ( hbmAttributeMapping instanceof JaxbHbmAnyAssociationType any ) {
attributes.getAnyMappingAttributes().add( transformAnyAttribute( any ) ); final PropertyInfo propertyInfo = managedTypeInfo.propertyInfoMap().get( any.getName() );
attributes.getAnyMappingAttributes().add( transformAnyAttribute( any, propertyInfo ) );
} }
else if ( hbmAttributeMapping instanceof PluralAttributeInfo hbmCollection ) { else if ( hbmAttributeMapping instanceof PluralAttributeInfo hbmCollection ) {
@ -1440,7 +1441,7 @@ public class HbmXmlTransformer {
JaxbBasicImpl basic, JaxbBasicImpl basic,
PropertyInfo propertyInfo) { PropertyInfo propertyInfo) {
basic.setName( hbmProp.getName() ); basic.setName( hbmProp.getName() );
basic.setOptional( hbmProp.isNotNull() == null || !hbmProp.isNotNull() ); basic.setOptional( propertyInfo.bootModelProperty().isOptional() );
basic.setFetch( FetchType.EAGER ); basic.setFetch( FetchType.EAGER );
basic.setAttributeAccessor( hbmProp.getAccess() ); basic.setAttributeAccessor( hbmProp.getAccess() );
basic.setOptimisticLock( hbmProp.isOptimisticLock() ); basic.setOptimisticLock( hbmProp.isOptimisticLock() );
@ -1506,7 +1507,7 @@ public class HbmXmlTransformer {
new ColumnDefaults() { new ColumnDefaults() {
@Override @Override
public Boolean isNullable() { public Boolean isNullable() {
return invert( hbmProp.isNotNull() ); return propertyInfo.bootModelProperty().isOptional();
} }
@Override @Override
@ -1642,9 +1643,10 @@ public class HbmXmlTransformer {
return embedded; return embedded;
} }
private void transferOneToOne(JaxbHbmOneToOneType hbmOneToOne, JaxbAttributesContainer attributes) { private void transferOneToOne(JaxbHbmOneToOneType hbmOneToOne, PropertyInfo propertyInfo, JaxbAttributesContainer attributes) {
final JaxbOneToOneImpl oneToOne = new JaxbOneToOneImpl(); final JaxbOneToOneImpl oneToOne = new JaxbOneToOneImpl();
oneToOne.setAttributeAccessor( hbmOneToOne.getAccess() ); oneToOne.setAttributeAccessor( hbmOneToOne.getAccess() );
oneToOne.setOptional( propertyInfo.bootModelProperty().isOptional() );
oneToOne.setCascade( convertCascadeType( hbmOneToOne.getCascade() ) ); oneToOne.setCascade( convertCascadeType( hbmOneToOne.getCascade() ) );
oneToOne.setOrphanRemoval( isOrphanRemoval( hbmOneToOne.getCascade() ) ); oneToOne.setOrphanRemoval( isOrphanRemoval( hbmOneToOne.getCascade() ) );
oneToOne.setForeignKey( new JaxbForeignKeyImpl() ); oneToOne.setForeignKey( new JaxbForeignKeyImpl() );
@ -1670,10 +1672,19 @@ public class HbmXmlTransformer {
attributes.getOneToOneAttributes().add( oneToOne ); attributes.getOneToOneAttributes().add( oneToOne );
} }
private void transferManyToOne(
ManagedTypeInfo managedTypeInfo,
JaxbAttributesContainer attributes,
JaxbHbmManyToOneType hbmManyToOne) {
final PropertyInfo propertyInfo = managedTypeInfo.propertyInfoMap().get( hbmManyToOne.getName() );
final JaxbManyToOneImpl jaxbManyToOne = transformManyToOne( hbmManyToOne, propertyInfo );
attributes.getManyToOneAttributes().add( jaxbManyToOne );
}
private JaxbManyToOneImpl transformManyToOne(JaxbHbmManyToOneType hbmNode, PropertyInfo propertyInfo) { private JaxbManyToOneImpl transformManyToOne(JaxbHbmManyToOneType hbmNode, PropertyInfo propertyInfo) {
final JaxbManyToOneImpl jaxbManyToOne = new JaxbManyToOneImpl(); final JaxbManyToOneImpl jaxbManyToOne = new JaxbManyToOneImpl();
jaxbManyToOne.setName( hbmNode.getName() ); jaxbManyToOne.setName( hbmNode.getName() );
jaxbManyToOne.setOptional( hbmNode.isNotNull() == null || !hbmNode.isNotNull() ); jaxbManyToOne.setOptional( propertyInfo.bootModelProperty().isOptional() );
if ( isNotEmpty( hbmNode.getEntityName() ) ) { if ( isNotEmpty( hbmNode.getEntityName() ) ) {
jaxbManyToOne.setTargetEntity( hbmNode.getEntityName() ); jaxbManyToOne.setTargetEntity( hbmNode.getEntityName() );
} }
@ -1740,12 +1751,13 @@ public class HbmXmlTransformer {
} }
private JaxbAnyMappingImpl transformAnyAttribute(JaxbHbmAnyAssociationType source) { private JaxbAnyMappingImpl transformAnyAttribute(JaxbHbmAnyAssociationType source, PropertyInfo propertyInfo) {
final JaxbAnyMappingImpl target = new JaxbAnyMappingImpl(); final JaxbAnyMappingImpl target = new JaxbAnyMappingImpl();
target.setName( source.getName() ); target.setName( source.getName() );
target.setAttributeAccessor( source.getAccess() ); target.setAttributeAccessor( source.getAccess() );
target.setOptimisticLock( source.isOptimisticLock() ); target.setOptimisticLock( source.isOptimisticLock() );
target.setOptional( propertyInfo.bootModelProperty().isOptional() );
// todo : cascade // todo : cascade
// todo : discriminator column // todo : discriminator column
@ -3087,12 +3099,12 @@ public class HbmXmlTransformer {
@Override @Override
public List<JaxbManyToOneImpl> getManyToOneAttributes() { public List<JaxbManyToOneImpl> getManyToOneAttributes() {
return null; return naturalId.getManyToOneAttributes();
} }
@Override @Override
public List<JaxbAnyMappingImpl> getAnyMappingAttributes() { public List<JaxbAnyMappingImpl> getAnyMappingAttributes() {
return null; return naturalId.getAnyMappingAttributes();
} }
@Override @Override

View File

@ -0,0 +1,15 @@
/*
* 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.jaxb.hbm.transform;
/**
* Used to model {@code hbm.xml} entity mapping where attributes come from
* @author Steve Ebersole
*/
public class MappedSuperclassTypeInfo {
// private final MappedSuperclassTypeInfo superclassTypeInfo;
}

View File

@ -24,6 +24,7 @@ import org.hibernate.boot.jaxb.mapping.spi.JaxbOneToOneImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbPersistentAttribute; import org.hibernate.boot.jaxb.mapping.spi.JaxbPersistentAttribute;
import org.hibernate.boot.jaxb.mapping.spi.JaxbPluralAnyMappingImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbPluralAnyMappingImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbTransientImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbTransientImpl;
import org.hibernate.boot.models.HibernateAnnotations;
import org.hibernate.boot.models.xml.internal.attr.AnyMappingAttributeProcessing; import org.hibernate.boot.models.xml.internal.attr.AnyMappingAttributeProcessing;
import org.hibernate.boot.models.xml.internal.attr.BasicAttributeProcessing; import org.hibernate.boot.models.xml.internal.attr.BasicAttributeProcessing;
import org.hibernate.boot.models.xml.internal.attr.CommonAttributeProcessing; import org.hibernate.boot.models.xml.internal.attr.CommonAttributeProcessing;
@ -66,7 +67,25 @@ public class AttributeProcessor {
XmlAnnotationHelper.applyNaturalIdCache( jaxbNaturalId, mutableClassDetails, xmlDocumentContext ); XmlAnnotationHelper.applyNaturalIdCache( jaxbNaturalId, mutableClassDetails, xmlDocumentContext );
processBaseAttributes( jaxbNaturalId, mutableClassDetails, classAccessType, memberAdjuster, xmlDocumentContext ); processBaseAttributes(
jaxbNaturalId,
mutableClassDetails,
classAccessType,
new MemberAdjuster() {
@Override
public <M extends MutableMemberDetails> void adjust(
M member,
JaxbPersistentAttribute jaxbPersistentAttribute,
XmlDocumentContext xmlDocumentContext) {
memberAdjuster.adjust( member, jaxbPersistentAttribute, xmlDocumentContext );
member.applyAnnotationUsage( HibernateAnnotations.NATURAL_ID, xmlDocumentContext.getModelBuildingContext() );
if ( !jaxbNaturalId.isMutable() ) {
member.applyAnnotationUsage( HibernateAnnotations.IMMUTABLE, xmlDocumentContext.getModelBuildingContext() );
}
}
},
xmlDocumentContext
);
} }
public static void processBaseAttributes( public static void processBaseAttributes(

View File

@ -0,0 +1,31 @@
/*
* 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.boot.models.hbm.mappedsuper;
/**
* @author Steve Ebersole
*/
public class Base {
private Integer id;
private String 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

@ -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.boot.models.hbm.mappedsuper;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.cfg.MappingSettings;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.DomainModelScope;
import org.hibernate.testing.orm.junit.FailureExpected;
import org.hibernate.testing.orm.junit.Jira;
import org.hibernate.testing.orm.junit.ServiceRegistry;
import org.hibernate.testing.orm.junit.Setting;
import org.junit.jupiter.api.Test;
/**
* @author Steve Ebersole
*/
@SuppressWarnings("JUnitMalformedDeclaration")
public class ImpliedMappedSuperTests {
@Test
@DomainModel( xmlMappings = "mappings/models/hbm/mappedsuper/implied-mapped-super.xml" )
void testHbm(DomainModelScope domainModelScope) {
verify( domainModelScope );
}
@Test
@FailureExpected( reason = "Support for implied mapped-superclass from hbm.xml is not implemented yet" )
@Jira( "https://hibernate.atlassian.net/browse/HHH-18387" )
@ServiceRegistry( settings = @Setting( name = MappingSettings.TRANSFORM_HBM_XML, value = "true" ) )
@DomainModel( xmlMappings = "mappings/models/hbm/mappedsuper/implied-mapped-super.xml" )
void testHbmTransformation(DomainModelScope domainModelScope) {
verify( domainModelScope );
}
private void verify(DomainModelScope domainModelScope) {
final PersistentClass thing1Binding = domainModelScope.getEntityBinding( Thing1.class );
final PersistentClass thing2Binding = domainModelScope.getEntityBinding( Thing2.class );
}
}

View File

@ -0,0 +1,22 @@
/*
* 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.boot.models.hbm.mappedsuper;
/**
* @author Steve Ebersole
*/
public class Thing1 extends Base {
private String stuff;
public String getStuff() {
return stuff;
}
public void setStuff(String stuff) {
this.stuff = stuff;
}
}

View File

@ -0,0 +1,22 @@
/*
* 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.boot.models.hbm.mappedsuper;
/**
* @author Steve Ebersole
*/
public class Thing2 extends Base {
private String data;
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}

View File

@ -33,12 +33,7 @@ import static org.junit.jupiter.api.Assertions.fail;
/** /**
* @author Gavin King * @author Gavin King
*/ */
@DomainModel( @DomainModel( xmlMappings = "org/hibernate/orm/test/mapping/inheritance/discriminator/SimpleInheritance.hbm.xml")
xmlMappings = {
"org/hibernate/orm/test/mapping/inheritance/discriminator/SimpleInheritance.hbm.xml",
"org/hibernate/orm/test/mapping/inheritance/discriminator/Person.hbm.xml"
}
)
@SessionFactory @SessionFactory
public class SimpleInheritanceTest { public class SimpleInheritanceTest {

View File

@ -0,0 +1,23 @@
<?xml version="1.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.
-->
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.hibernate.orm.test.boot.models.hbm.mappedsuper">
<class name="Thing1">
<id name="id"/>
<property name="name"/>
<property name="stuff"/>
</class>
<class name="Thing2">
<id name="id"/>
<property name="name"/>
<property name="data"/>
</class>
</hibernate-mapping>