HHH-18265 HbmXmlTransformer transform hbm <key column=/>

This commit is contained in:
Andrea Boriero 2024-06-13 12:17:02 +02:00 committed by Steve Ebersole
parent 07db16cf7f
commit e5b86f31f2
6 changed files with 331 additions and 62 deletions

View File

@ -139,6 +139,7 @@ import org.hibernate.boot.jaxb.mapping.spi.JaxbHqlImportImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbIdClassImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbIdClassImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbIdImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbIdImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbJoinColumnImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbJoinColumnImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbJoinTableImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbManyToManyImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbManyToManyImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbManyToOneImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbManyToOneImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbMapKeyColumnImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbMapKeyColumnImpl;
@ -1088,7 +1089,7 @@ public class HbmXmlTransformer {
private void transferDiscriminatorSubclass(JaxbHbmDiscriminatorSubclassEntityType hbmSubclass, JaxbEntityImpl subclassEntity) { private void transferDiscriminatorSubclass(JaxbHbmDiscriminatorSubclassEntityType hbmSubclass, JaxbEntityImpl subclassEntity) {
TRANSFORMATION_LOGGER.debugf( TRANSFORMATION_LOGGER.debugf(
"Starting transformation of subclass entity `%` - `%s`", "Starting transformation of subclass entity `%s` - `%s`",
extractEntityName( hbmSubclass ), extractEntityName( hbmSubclass ),
origin origin
); );
@ -1133,11 +1134,23 @@ public class HbmXmlTransformer {
subclassEntity.getTable().getCheckConstraints().add( checkConstraint ); subclassEntity.getTable().getCheckConstraints().add( checkConstraint );
} }
if ( hbmSubclass.getKey() != null ) { final JaxbHbmKeyType key = hbmSubclass.getKey();
if ( key != null ) {
final JaxbPrimaryKeyJoinColumnImpl joinColumn = new JaxbPrimaryKeyJoinColumnImpl(); final JaxbPrimaryKeyJoinColumnImpl joinColumn = new JaxbPrimaryKeyJoinColumnImpl();
// TODO: multiple columns? // TODO: multiple columns?
joinColumn.setName( hbmSubclass.getKey().getColumnAttribute() ); joinColumn.setName( key.getColumnAttribute() );
subclassEntity.getPrimaryKeyJoinColumns().add( joinColumn ); subclassEntity.getPrimaryKeyJoinColumns().add( joinColumn );
final String foreignKey = key.getForeignKey();
if ( StringHelper.isNotEmpty( foreignKey ) ) {
final JaxbForeignKeyImpl jaxbForeignKey = new JaxbForeignKeyImpl();
joinColumn.setForeignKey( jaxbForeignKey );
if ( "none".equals( foreignKey ) ) {
jaxbForeignKey.setConstraintMode( ConstraintMode.NO_CONSTRAINT );
}
else {
jaxbForeignKey.setName( foreignKey );
}
}
} }
if ( !hbmSubclass.getJoinedSubclass().isEmpty() ) { if ( !hbmSubclass.getJoinedSubclass().isEmpty() ) {
@ -1729,17 +1742,31 @@ public class HbmXmlTransformer {
final JaxbElementCollectionImpl target) { final JaxbElementCollectionImpl target) {
target.setCollectionTable( new JaxbCollectionTableImpl() ); target.setCollectionTable( new JaxbCollectionTableImpl() );
final JaxbCollectionTableImpl collectionTable = target.getCollectionTable();
if ( isNotEmpty( source.getTable() ) ) { if ( isNotEmpty( source.getTable() ) ) {
target.getCollectionTable().setName( source.getTable() ); collectionTable.setName( source.getTable() );
target.getCollectionTable().setCatalog( source.getCatalog() ); collectionTable.setCatalog( source.getCatalog() );
target.getCollectionTable().setSchema( source.getSchema() ); collectionTable.setSchema( source.getSchema() );
}
final JaxbHbmKeyType key = source.getKey();
if ( key != null ) {
final String foreignKey = key.getForeignKey();
if ( StringHelper.isNotEmpty( foreignKey ) ) {
final JaxbForeignKeyImpl jaxbForeignKey = new JaxbForeignKeyImpl();
collectionTable.setForeignKeys( jaxbForeignKey );
if ( "none".equals( foreignKey ) ) {
jaxbForeignKey.setConstraintMode( ConstraintMode.NO_CONSTRAINT );
}
else {
jaxbForeignKey.setName( foreignKey );
}
} }
transferColumnsAndFormulas( transferColumnsAndFormulas(
new ColumnAndFormulaSource() { new ColumnAndFormulaSource() {
@Override @Override
public String getColumnAttribute() { public String getColumnAttribute() {
return source.getKey().getColumnAttribute(); return key.getColumnAttribute();
} }
@Override @Override
@ -1749,7 +1776,7 @@ public class HbmXmlTransformer {
@Override @Override
public List<Serializable> getColumnOrFormula() { public List<Serializable> getColumnOrFormula() {
return new ArrayList<>( source.getKey().getColumn() ); return new ArrayList<>( key.getColumn() );
} }
@Override @Override
@ -1765,7 +1792,8 @@ public class HbmXmlTransformer {
@Override @Override
public void addColumn(TargetColumnAdapter column) { public void addColumn(TargetColumnAdapter column) {
collectionTable.getJoinColumns()
.add( ( (TargetColumnAdapterJaxbJoinColumn) column ).getTargetColumn() );
} }
@Override @Override
@ -1780,7 +1808,7 @@ public class HbmXmlTransformer {
); );
if ( isNotEmpty( source.getKey().getPropertyRef() ) ) { if ( isNotEmpty( key.getPropertyRef() ) ) {
handleUnsupportedContent( handleUnsupportedContent(
"Foreign-key (<key/>) for persistent collection (name=" + source.getName() + "Foreign-key (<key/>) for persistent collection (name=" + source.getName() +
") specified property-ref which is not supported for transformation; " + ") specified property-ref which is not supported for transformation; " +
@ -1788,6 +1816,7 @@ public class HbmXmlTransformer {
); );
} }
} }
}
private void transferCollectionBasicInfo(PluralAttributeInfo source, JaxbPluralAttribute target) { private void transferCollectionBasicInfo(PluralAttributeInfo source, JaxbPluralAttribute target) {
@ -2116,15 +2145,64 @@ public class HbmXmlTransformer {
final JaxbHbmKeyType key = hbmAttributeInfo.getKey(); final JaxbHbmKeyType key = hbmAttributeInfo.getKey();
if ( key != null ) { if ( key != null ) {
target.setForeignKey( new JaxbForeignKeyImpl() ); final String foreignKey = key.getForeignKey();
if ( StringHelper.isNotEmpty( key.getForeignKey() ) ) { if ( StringHelper.isNotEmpty( foreignKey ) ) {
target.getForeignKey().setName( key.getForeignKey() ); final JaxbForeignKeyImpl jaxbForeignKey = new JaxbForeignKeyImpl();
target.setForeignKey( jaxbForeignKey );
if ( "none".equals( foreignKey ) ) {
jaxbForeignKey.setConstraintMode( ConstraintMode.NO_CONSTRAINT );
} }
// oneToMany.setCollectionId( ? ); else {
// oneToMany.setMappedBy( ?? ); jaxbForeignKey.setName( foreignKey );
// oneToMany.setOnDelete( ?? ); }
}
// if ( StringHelper.isNotEmpty( key.getColumnAttribute() ) ) {
// final JaxbJoinColumnImpl column = new JaxbJoinColumnImpl();
// column.setName( key.getColumnAttribute() );
// target.getJoinColumn().add( column );
// }
transferColumnsAndFormulas(
new ColumnAndFormulaSource() {
@Override
public String getColumnAttribute() {
return key.getColumnAttribute();
} }
@Override
public String getFormulaAttribute() {
return null;
}
@Override
public List<Serializable> getColumnOrFormula() {
return new ArrayList<>(key.getColumn());
}
@Override
public SourceColumnAdapter wrap(Serializable column) {
return new SourceColumnAdapterJaxbHbmColumnType( (JaxbHbmColumnType) column );
}
},
new ColumnAndFormulaTarget() {
@Override
public TargetColumnAdapter makeColumnAdapter(ColumnDefaults columnDefaults) {
return new TargetColumnAdapterJaxbJoinColumn( columnDefaults );
}
@Override
public void addColumn(TargetColumnAdapter column) {
target.getJoinColumn().add( ( (TargetColumnAdapterJaxbJoinColumn) column ).getTargetColumn() );
}
@Override
public void addFormula(String formula) {
}
},
ColumnDefaultsBasicImpl.INSTANCE,
currentTableName
);
}
if ( hbmOneToMany.getNotFound() != null ) { if ( hbmOneToMany.getNotFound() != null ) {
target.setNotFound( interpretNotFoundAction( hbmOneToMany.getNotFound() ) ); target.setNotFound( interpretNotFoundAction( hbmOneToMany.getNotFound() ) );
} }
@ -2176,6 +2254,111 @@ public class HbmXmlTransformer {
handleUnsupported( "`not-found` not supported for transformation" ); handleUnsupported( "`not-found` not supported for transformation" );
} }
final JaxbJoinTableImpl joinTable = new JaxbJoinTableImpl();
final String tableName = hbmCollection.getTable();
if ( StringHelper.isNotEmpty( tableName ) ) {
joinTable.setName( tableName );
}
target.setJoinTable( joinTable );
final JaxbHbmKeyType key = hbmCollection.getKey();
if ( key != null ) {
final String foreignKey = key.getForeignKey();
if ( StringHelper.isNotEmpty( foreignKey ) ) {
final JaxbForeignKeyImpl jaxbForeignKey = new JaxbForeignKeyImpl();
joinTable.setForeignKey( jaxbForeignKey );
if ( "none".equals( foreignKey ) ) {
jaxbForeignKey.setConstraintMode( ConstraintMode.NO_CONSTRAINT );
}
else {
jaxbForeignKey.setName( foreignKey );
}
}
transferColumnsAndFormulas(
new ColumnAndFormulaSource() {
@Override
public String getColumnAttribute() {
return key.getColumnAttribute();
}
@Override
public String getFormulaAttribute() {
return "";
}
@Override
public List<Serializable> getColumnOrFormula() {
return new ArrayList<>(key.getColumn());
}
@Override
public SourceColumnAdapter wrap(Serializable column) {
return new SourceColumnAdapterJaxbHbmColumnType( (JaxbHbmColumnType) column );
}
},
new ColumnAndFormulaTarget() {
@Override
public TargetColumnAdapter makeColumnAdapter(ColumnDefaults columnDefaults) {
return new TargetColumnAdapterJaxbJoinColumn( columnDefaults );
}
@Override
public void addColumn(TargetColumnAdapter column) {
joinTable.getJoinColumn().add( ( (TargetColumnAdapterJaxbJoinColumn) column ).getTargetColumn() );
}
@Override
public void addFormula(String formula) {
}
},
ColumnDefaultsBasicImpl.INSTANCE,
joinTable.getName()
);
}
transferColumnsAndFormulas(
new ColumnAndFormulaSource() {
@Override
public String getColumnAttribute() {
return manyToMany.getColumnAttribute();
}
@Override
public String getFormulaAttribute() {
return manyToMany.getFormulaAttribute();
}
@Override
public List<Serializable> getColumnOrFormula() {
return manyToMany.getColumnOrFormula();
}
@Override
public SourceColumnAdapter wrap(Serializable column) {
return new SourceColumnAdapterJaxbHbmColumnType( (JaxbHbmColumnType) column );
}
},
new ColumnAndFormulaTarget() {
@Override
public TargetColumnAdapter makeColumnAdapter(ColumnDefaults columnDefaults) {
return new TargetColumnAdapterJaxbJoinColumn( columnDefaults );
}
@Override
public void addColumn(TargetColumnAdapter column) {
joinTable.getInverseJoinColumn().add( ( (TargetColumnAdapterJaxbJoinColumn) column ).getTargetColumn() );
}
@Override
public void addFormula(String formula) {
handleUnsupported( "<many-to-many formula> not supported skipping" );
}
},
ColumnDefaultsBasicImpl.INSTANCE,
joinTable.getName()
);
transferCollectionBasicInfo( hbmCollection, target ); transferCollectionBasicInfo( hbmCollection, target );
target.setTargetEntity( StringHelper.isNotEmpty( manyToMany.getClazz() ) ? manyToMany.getClazz() : manyToMany.getEntityName() ); target.setTargetEntity( StringHelper.isNotEmpty( manyToMany.getClazz() ) ? manyToMany.getClazz() : manyToMany.getEntityName() );
@ -2445,10 +2628,22 @@ public class HbmXmlTransformer {
secondaryTable.setSchema( hbmJoin.getSchema() ); secondaryTable.setSchema( hbmJoin.getSchema() );
secondaryTable.setOptional( hbmJoin.isOptional() ); secondaryTable.setOptional( hbmJoin.isOptional() );
secondaryTable.setOwned( !hbmJoin.isInverse() ); secondaryTable.setOwned( !hbmJoin.isInverse() );
if ( hbmJoin.getKey() != null ) { final JaxbHbmKeyType key = hbmJoin.getKey();
if ( key != null ) {
final JaxbPrimaryKeyJoinColumnImpl joinColumn = new JaxbPrimaryKeyJoinColumnImpl(); final JaxbPrimaryKeyJoinColumnImpl joinColumn = new JaxbPrimaryKeyJoinColumnImpl();
joinColumn.setName( hbmJoin.getKey().getColumnAttribute() ); joinColumn.setName( key.getColumnAttribute() );
secondaryTable.getPrimaryKeyJoinColumn().add( joinColumn ); secondaryTable.getPrimaryKeyJoinColumn().add( joinColumn );
final String foreignKey = key.getForeignKey();
if ( StringHelper.isNotEmpty( foreignKey ) ) {
final JaxbForeignKeyImpl jaxbForeignKey = new JaxbForeignKeyImpl();
joinColumn.setForeignKey( jaxbForeignKey );
if ( "none".equals( foreignKey ) ) {
jaxbForeignKey.setConstraintMode( ConstraintMode.NO_CONSTRAINT );
}
else {
jaxbForeignKey.setName( foreignKey );
}
}
} }
target.getSecondaryTables().add( secondaryTable ); target.getSecondaryTables().add( secondaryTable );

View File

@ -19,4 +19,20 @@ public class Category {
@ManyToOne @ManyToOne
@JoinColumn(name = "owner_fk") @JoinColumn(name = "owner_fk")
private User owner; private User owner;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public User getOwner() {
return owner;
}
public void setOwner(User owner) {
this.owner = owner;
}
} }

View File

@ -13,11 +13,14 @@ import org.hibernate.mapping.List;
import org.hibernate.mapping.ManyToOne; import org.hibernate.mapping.ManyToOne;
import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property; import org.hibernate.mapping.Property;
import org.hibernate.mapping.Table;
import org.hibernate.mapping.Value; import org.hibernate.mapping.Value;
import org.hibernate.testing.orm.junit.DomainModel; import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.DomainModelScope; import org.hibernate.testing.orm.junit.DomainModelScope;
import org.hibernate.testing.orm.junit.ServiceRegistry; import org.hibernate.testing.orm.junit.ServiceRegistry;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.hibernate.testing.orm.junit.Setting; import org.hibernate.testing.orm.junit.Setting;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -31,10 +34,15 @@ import static org.assertj.core.api.Assertions.fail;
public class ListTests { public class ListTests {
@Test @Test
@DomainModel( xmlMappings = "mappings/models/hbm/list/hbm.xml" ) @DomainModel( xmlMappings = "mappings/models/hbm/list/hbm.xml" )
void testHbmXml(DomainModelScope domainModelScope) { void testHbmXml(DomainModelScope domainModelScope) {
final PersistentClass rootBinding = domainModelScope.getDomainModel().getEntityBinding( Root.class.getName() ); final PersistentClass rootBinding = domainModelScope.getDomainModel().getEntityBinding( Root.class.getName() );
validateTags( rootBinding.getProperty( "tags" ) ); validateTags( rootBinding.getProperty( "tags" ) );
validateCategories( rootBinding.getProperty( "categories" ) ); validateCategories( rootBinding.getProperty( "categories" ) );
Property admins = rootBinding.getProperty( "admins" );
Table collectionTable = ( (List) admins.getValue() ).getCollectionTable();
// collectionTable.getColumns().
Property admins2 = rootBinding.getProperty( "admins2" );
} }
@Test @Test

View File

@ -30,10 +30,13 @@ public class Root {
@ElementCollection @ElementCollection
@CollectionTable(name="root_categories") @CollectionTable(name="root_categories")
@OrderColumn(name = "position") @OrderColumn(name = "position")
private List<String> categories; private List<Category> categories;
@ManyToMany @ManyToMany
@CollectionTable(name="root_admins") @CollectionTable(name="root_admins")
private List<User> admins; private List<User> admins;
@ManyToMany
@CollectionTable(name="root_admins_2")
private List<User> admins2;
protected Root() { protected Root() {
@ -49,6 +52,10 @@ public class Root {
return id; return id;
} }
public void setId(Integer id) {
this.id = id;
}
public String getName() { public String getName() {
return name; return name;
} }
@ -56,4 +63,36 @@ public class Root {
public void setName(String name) { public void setName(String name) {
this.name = name; this.name = name;
} }
public List<String> getTags() {
return tags;
}
public void setTags(List<String> tags) {
this.tags = tags;
}
public List<Category> getCategories() {
return categories;
}
public void setCategories(List<Category> categories) {
this.categories = categories;
}
public List<User> getAdmins() {
return admins;
}
public void setAdmins(List<User> admins) {
this.admins = admins;
}
public List<User> getAdmins2() {
return admins2;
}
public void setAdmins2(List<User> admins2) {
this.admins2 = admins2;
}
} }

View File

@ -35,6 +35,10 @@ public class User {
return id; return id;
} }
public void setId(Integer id) {
this.id = id;
}
public String getName() { public String getName() {
return name; return name;
} }

View File

@ -22,7 +22,7 @@
<element column="txt" type="string"/> <element column="txt" type="string"/>
</list> </list>
<list name="categories" table="root_categories"> <list name="categories" table="root_categories">
<key column="root_fk"/> <key column="root_fk" foreign-key="none"/>
<list-index column="position"/> <list-index column="position"/>
<composite-element class="org.hibernate.orm.test.boot.models.hbm.collections.list.Category"> <composite-element class="org.hibernate.orm.test.boot.models.hbm.collections.list.Category">
<property name="name"/> <property name="name"/>
@ -34,9 +34,16 @@
<list-index/> <list-index/>
<many-to-many class="org.hibernate.orm.test.boot.models.hbm.collections.list.User" column="user_fk"/> <many-to-many class="org.hibernate.orm.test.boot.models.hbm.collections.list.User" column="user_fk"/>
</list> </list>
<list name="admins2" table="root_admins_2">
<key column="root_fk"/>
<list-index/>
<one-to-many class="org.hibernate.orm.test.boot.models.hbm.collections.list.User" />
</list>
</class> </class>
<class name="org.hibernate.orm.test.boot.models.hbm.collections.list.User"> <class name="org.hibernate.orm.test.boot.models.hbm.collections.list.User" table="users">
<id/> <id/>
<property name="name"/> <property name="name"/>
</class> </class>