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.JaxbIdImpl;
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.JaxbManyToOneImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbMapKeyColumnImpl;
@ -1088,7 +1089,7 @@ public class HbmXmlTransformer {
private void transferDiscriminatorSubclass(JaxbHbmDiscriminatorSubclassEntityType hbmSubclass, JaxbEntityImpl subclassEntity) {
TRANSFORMATION_LOGGER.debugf(
"Starting transformation of subclass entity `%` - `%s`",
"Starting transformation of subclass entity `%s` - `%s`",
extractEntityName( hbmSubclass ),
origin
);
@ -1133,11 +1134,23 @@ public class HbmXmlTransformer {
subclassEntity.getTable().getCheckConstraints().add( checkConstraint );
}
if ( hbmSubclass.getKey() != null ) {
final JaxbHbmKeyType key = hbmSubclass.getKey();
if ( key != null ) {
final JaxbPrimaryKeyJoinColumnImpl joinColumn = new JaxbPrimaryKeyJoinColumnImpl();
// TODO: multiple columns?
joinColumn.setName( hbmSubclass.getKey().getColumnAttribute() );
joinColumn.setName( key.getColumnAttribute() );
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() ) {
@ -1729,63 +1742,79 @@ public class HbmXmlTransformer {
final JaxbElementCollectionImpl target) {
target.setCollectionTable( new JaxbCollectionTableImpl() );
final JaxbCollectionTableImpl collectionTable = target.getCollectionTable();
if ( isNotEmpty( source.getTable() ) ) {
target.getCollectionTable().setName( source.getTable() );
target.getCollectionTable().setCatalog( source.getCatalog() );
target.getCollectionTable().setSchema( source.getSchema() );
collectionTable.setName( source.getTable() );
collectionTable.setCatalog( source.getCatalog() );
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(
new ColumnAndFormulaSource() {
@Override
public String getColumnAttribute() {
return source.getKey().getColumnAttribute();
}
transferColumnsAndFormulas(
new ColumnAndFormulaSource() {
@Override
public String getColumnAttribute() {
return key.getColumnAttribute();
}
@Override
public String getFormulaAttribute() {
return null;
}
@Override
public String getFormulaAttribute() {
return null;
}
@Override
public List<Serializable> getColumnOrFormula() {
return new ArrayList<>( source.getKey().getColumn() );
}
@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 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) {
@Override
public void addColumn(TargetColumnAdapter column) {
collectionTable.getJoinColumns()
.add( ( (TargetColumnAdapterJaxbJoinColumn) column ).getTargetColumn() );
}
}
@Override
public void addFormula(String formula) {
handleUnsupportedContent(
"formula as part of element-collection key is not supported for transformation; skipping"
);
}
},
ColumnDefaultsBasicImpl.INSTANCE,
source.getTable()
@Override
public void addFormula(String formula) {
handleUnsupportedContent(
"formula as part of element-collection key is not supported for transformation; skipping"
);
}
},
ColumnDefaultsBasicImpl.INSTANCE,
source.getTable()
);
if ( isNotEmpty( source.getKey().getPropertyRef() ) ) {
handleUnsupportedContent(
"Foreign-key (<key/>) for persistent collection (name=" + source.getName() +
") specified property-ref which is not supported for transformation; " +
"transformed <join-column/> will need manual adjustment of referenced-column-name"
);
if ( isNotEmpty( key.getPropertyRef() ) ) {
handleUnsupportedContent(
"Foreign-key (<key/>) for persistent collection (name=" + source.getName() +
") specified property-ref which is not supported for transformation; " +
"transformed <join-column/> will need manual adjustment of referenced-column-name"
);
}
}
}
@ -2116,15 +2145,64 @@ public class HbmXmlTransformer {
final JaxbHbmKeyType key = hbmAttributeInfo.getKey();
if ( key != null ) {
target.setForeignKey( new JaxbForeignKeyImpl() );
if ( StringHelper.isNotEmpty( key.getForeignKey() ) ) {
target.getForeignKey().setName( key.getForeignKey() );
final String foreignKey = key.getForeignKey();
if ( StringHelper.isNotEmpty( foreignKey ) ) {
final JaxbForeignKeyImpl jaxbForeignKey = new JaxbForeignKeyImpl();
target.setForeignKey( jaxbForeignKey );
if ( "none".equals( foreignKey ) ) {
jaxbForeignKey.setConstraintMode( ConstraintMode.NO_CONSTRAINT );
}
else {
jaxbForeignKey.setName( foreignKey );
}
}
// oneToMany.setCollectionId( ? );
// oneToMany.setMappedBy( ?? );
// 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 ) {
target.setNotFound( interpretNotFoundAction( hbmOneToMany.getNotFound() ) );
}
@ -2176,6 +2254,111 @@ public class HbmXmlTransformer {
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 );
target.setTargetEntity( StringHelper.isNotEmpty( manyToMany.getClazz() ) ? manyToMany.getClazz() : manyToMany.getEntityName() );
@ -2445,10 +2628,22 @@ public class HbmXmlTransformer {
secondaryTable.setSchema( hbmJoin.getSchema() );
secondaryTable.setOptional( hbmJoin.isOptional() );
secondaryTable.setOwned( !hbmJoin.isInverse() );
if ( hbmJoin.getKey() != null ) {
final JaxbHbmKeyType key = hbmJoin.getKey();
if ( key != null ) {
final JaxbPrimaryKeyJoinColumnImpl joinColumn = new JaxbPrimaryKeyJoinColumnImpl();
joinColumn.setName( hbmJoin.getKey().getColumnAttribute() );
joinColumn.setName( key.getColumnAttribute() );
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 );

View File

@ -19,4 +19,20 @@ public class Category {
@ManyToOne
@JoinColumn(name = "owner_fk")
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.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.Table;
import org.hibernate.mapping.Value;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.DomainModelScope;
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.junit.jupiter.api.Test;
@ -31,10 +34,15 @@ import static org.assertj.core.api.Assertions.fail;
public class ListTests {
@Test
@DomainModel( xmlMappings = "mappings/models/hbm/list/hbm.xml" )
void testHbmXml(DomainModelScope domainModelScope) {
final PersistentClass rootBinding = domainModelScope.getDomainModel().getEntityBinding( Root.class.getName() );
validateTags( rootBinding.getProperty( "tags" ) );
validateCategories( rootBinding.getProperty( "categories" ) );
Property admins = rootBinding.getProperty( "admins" );
Table collectionTable = ( (List) admins.getValue() ).getCollectionTable();
// collectionTable.getColumns().
Property admins2 = rootBinding.getProperty( "admins2" );
}
@Test

View File

@ -30,10 +30,13 @@ public class Root {
@ElementCollection
@CollectionTable(name="root_categories")
@OrderColumn(name = "position")
private List<String> categories;
private List<Category> categories;
@ManyToMany
@CollectionTable(name="root_admins")
private List<User> admins;
@ManyToMany
@CollectionTable(name="root_admins_2")
private List<User> admins2;
protected Root() {
@ -49,6 +52,10 @@ public class Root {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
@ -56,4 +63,36 @@ public class Root {
public void setName(String 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;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}

View File

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