HHH-18396 - Transform property-ref for one-to-one
This commit is contained in:
parent
5c993efde3
commit
bfd63ec5a5
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import org.hibernate.mapping.Property;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class ColumnDefaultsProperty implements ColumnDefaults {
|
||||||
|
private final Property property;
|
||||||
|
|
||||||
|
public ColumnDefaultsProperty(Property property) {
|
||||||
|
this.property = property;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean isNullable() {
|
||||||
|
return property.isOptional();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean isInsertable() {
|
||||||
|
return property.isInsertable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean isUpdateable() {
|
||||||
|
return property.isUpdateable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getLength() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getScale() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getPrecision() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean isUnique() {
|
||||||
|
return Boolean.FALSE;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1173,7 +1173,8 @@ public class HbmXmlTransformer {
|
||||||
ColumnAndFormulaTarget target,
|
ColumnAndFormulaTarget target,
|
||||||
ColumnDefaults columnDefaults,
|
ColumnDefaults columnDefaults,
|
||||||
String table) {
|
String table) {
|
||||||
for ( Selectable selectable : value.getSelectables() ) {
|
for ( int i = 0; i < value.getSelectables().size(); i++ ) {
|
||||||
|
final Selectable selectable = value.getSelectables().get( i );
|
||||||
if ( selectable instanceof Formula formula ) {
|
if ( selectable instanceof Formula formula ) {
|
||||||
target.addFormula( formula.getFormula() );
|
target.addFormula( formula.getFormula() );
|
||||||
}
|
}
|
||||||
|
@ -1181,12 +1182,18 @@ public class HbmXmlTransformer {
|
||||||
final TargetColumnAdapter targetColumnAdapter = target.makeColumnAdapter( columnDefaults );
|
final TargetColumnAdapter targetColumnAdapter = target.makeColumnAdapter( columnDefaults );
|
||||||
targetColumnAdapter.setName( column.getQuotedName() );
|
targetColumnAdapter.setName( column.getQuotedName() );
|
||||||
targetColumnAdapter.setTable( table );
|
targetColumnAdapter.setTable( table );
|
||||||
// todo (7.0) : account for #insert, #update, etc
|
targetColumnAdapter.setLength( convertColumnLength( column.getLength() ) );
|
||||||
|
targetColumnAdapter.setPrecision( column.getPrecision() );
|
||||||
|
targetColumnAdapter.setScale( column.getScale() );
|
||||||
target.addColumn( targetColumnAdapter );
|
target.addColumn( targetColumnAdapter );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Integer convertColumnLength(Long length) {
|
||||||
|
return length == null ? null : length.intValue();
|
||||||
|
}
|
||||||
|
|
||||||
private void transferColumnsAndFormulas(
|
private void transferColumnsAndFormulas(
|
||||||
ColumnAndFormulaSource source,
|
ColumnAndFormulaSource source,
|
||||||
ColumnAndFormulaTarget target,
|
ColumnAndFormulaTarget target,
|
||||||
|
@ -1709,10 +1716,9 @@ public class HbmXmlTransformer {
|
||||||
oneToOne.setOrphanRemoval( isOrphanRemoval( hbmOneToOne.getCascade() ) );
|
oneToOne.setOrphanRemoval( isOrphanRemoval( hbmOneToOne.getCascade() ) );
|
||||||
oneToOne.setForeignKey( new JaxbForeignKeyImpl() );
|
oneToOne.setForeignKey( new JaxbForeignKeyImpl() );
|
||||||
oneToOne.getForeignKey().setName( hbmOneToOne.getForeignKey() );
|
oneToOne.getForeignKey().setName( hbmOneToOne.getForeignKey() );
|
||||||
if (! StringHelper.isEmpty( hbmOneToOne.getPropertyRef() ) ) {
|
if ( StringHelper.isNotEmpty( hbmOneToOne.getPropertyRef() ) ) {
|
||||||
final JaxbJoinColumnImpl joinColumn = new JaxbJoinColumnImpl();
|
oneToOne.setPropertyRef( new JaxbPropertyRefImpl() );
|
||||||
joinColumn.setReferencedColumnName( hbmOneToOne.getPropertyRef() );
|
oneToOne.getPropertyRef().setName( hbmOneToOne.getPropertyRef() );
|
||||||
oneToOne.getJoinColumnOrJoinFormula().add( joinColumn );
|
|
||||||
}
|
}
|
||||||
for ( String formula : hbmOneToOne.getFormula() ) {
|
for ( String formula : hbmOneToOne.getFormula() ) {
|
||||||
oneToOne.getJoinColumnOrJoinFormula().add( formula );
|
oneToOne.getJoinColumnOrJoinFormula().add( formula );
|
||||||
|
@ -1780,7 +1786,7 @@ public class HbmXmlTransformer {
|
||||||
jaxbManyToOne.getJoinColumnOrJoinFormula().add( formula );
|
jaxbManyToOne.getJoinColumnOrJoinFormula().add( formula );
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ColumnDefaultsBasicImpl.INSTANCE,
|
new ColumnDefaultsProperty( manyToOneProperty ),
|
||||||
propertyInfo.tableName()
|
propertyInfo.tableName()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -3001,7 +3007,7 @@ public class HbmXmlTransformer {
|
||||||
hbmCompositeId.getKeyPropertyOrKeyManyToOne().forEach( (hbmIdProperty) -> {
|
hbmCompositeId.getKeyPropertyOrKeyManyToOne().forEach( (hbmIdProperty) -> {
|
||||||
if ( hbmIdProperty instanceof JaxbHbmCompositeKeyBasicAttributeType hbmKeyProperty ) {
|
if ( hbmIdProperty instanceof JaxbHbmCompositeKeyBasicAttributeType hbmKeyProperty ) {
|
||||||
final PropertyInfo keyPropertyInfo = componentTypeInfo.propertyInfoMap().get( hbmKeyProperty.getName() );
|
final PropertyInfo keyPropertyInfo = componentTypeInfo.propertyInfoMap().get( hbmKeyProperty.getName() );
|
||||||
mappingXmlEntity.getAttributes().getIdAttributes().add( transformNonAggregatedIdProperty(
|
mappingXmlEntity.getAttributes().getIdAttributes().add( transformNonAggregatedKeyProperty(
|
||||||
hbmKeyProperty,
|
hbmKeyProperty,
|
||||||
keyPropertyInfo
|
keyPropertyInfo
|
||||||
) );
|
) );
|
||||||
|
@ -3022,7 +3028,7 @@ public class HbmXmlTransformer {
|
||||||
throw new UnsupportedOperationException( "Not implemented yet" );
|
throw new UnsupportedOperationException( "Not implemented yet" );
|
||||||
}
|
}
|
||||||
|
|
||||||
private JaxbIdImpl transformNonAggregatedIdProperty(
|
private JaxbIdImpl transformNonAggregatedKeyProperty(
|
||||||
JaxbHbmCompositeKeyBasicAttributeType hbmIdProperty,
|
JaxbHbmCompositeKeyBasicAttributeType hbmIdProperty,
|
||||||
PropertyInfo idPropertyInfo) {
|
PropertyInfo idPropertyInfo) {
|
||||||
final JaxbIdImpl jaxbBasic = new JaxbIdImpl();
|
final JaxbIdImpl jaxbBasic = new JaxbIdImpl();
|
||||||
|
@ -3058,7 +3064,8 @@ public class HbmXmlTransformer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Serializable> getColumnOrFormula() {
|
public List<Serializable> getColumnOrFormula() {
|
||||||
return Collections.emptyList();
|
//noinspection unchecked,rawtypes
|
||||||
|
return (List) hbmIdProperty.getColumn();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -7,9 +7,11 @@
|
||||||
package org.hibernate.boot.models.xml.internal.attr;
|
package org.hibernate.boot.models.xml.internal.attr;
|
||||||
|
|
||||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbOneToOneImpl;
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbOneToOneImpl;
|
||||||
|
import org.hibernate.boot.models.HibernateAnnotations;
|
||||||
import org.hibernate.boot.models.JpaAnnotations;
|
import org.hibernate.boot.models.JpaAnnotations;
|
||||||
import org.hibernate.boot.models.XmlAnnotations;
|
import org.hibernate.boot.models.XmlAnnotations;
|
||||||
import org.hibernate.boot.models.annotations.internal.OneToOneJpaAnnotation;
|
import org.hibernate.boot.models.annotations.internal.OneToOneJpaAnnotation;
|
||||||
|
import org.hibernate.boot.models.annotations.internal.PropertyRefAnnotation;
|
||||||
import org.hibernate.boot.models.annotations.internal.TargetXmlAnnotation;
|
import org.hibernate.boot.models.annotations.internal.TargetXmlAnnotation;
|
||||||
import org.hibernate.boot.models.xml.internal.XmlProcessingHelper;
|
import org.hibernate.boot.models.xml.internal.XmlProcessingHelper;
|
||||||
import org.hibernate.boot.models.xml.internal.db.JoinColumnProcessing;
|
import org.hibernate.boot.models.xml.internal.db.JoinColumnProcessing;
|
||||||
|
@ -62,6 +64,14 @@ public class OneToOneAttributeProcessing {
|
||||||
JoinColumnProcessing.applyJoinColumnsOrFormulas( jaxbOneToOne.getJoinColumnOrJoinFormula(), memberDetails, xmlDocumentContext );
|
JoinColumnProcessing.applyJoinColumnsOrFormulas( jaxbOneToOne.getJoinColumnOrJoinFormula(), memberDetails, xmlDocumentContext );
|
||||||
JoinColumnProcessing.applyPrimaryKeyJoinColumns( jaxbOneToOne.getPrimaryKeyJoinColumn(), memberDetails, xmlDocumentContext );
|
JoinColumnProcessing.applyPrimaryKeyJoinColumns( jaxbOneToOne.getPrimaryKeyJoinColumn(), memberDetails, xmlDocumentContext );
|
||||||
|
|
||||||
|
if ( jaxbOneToOne.getPropertyRef() != null ) {
|
||||||
|
final PropertyRefAnnotation propertyRefUsage = (PropertyRefAnnotation) memberDetails.applyAnnotationUsage(
|
||||||
|
HibernateAnnotations.PROPERTY_REF,
|
||||||
|
xmlDocumentContext.getModelBuildingContext()
|
||||||
|
);
|
||||||
|
propertyRefUsage.value( jaxbOneToOne.getPropertyRef().getName() );
|
||||||
|
}
|
||||||
|
|
||||||
if ( jaxbOneToOne.isId() == Boolean.TRUE ) {
|
if ( jaxbOneToOne.isId() == Boolean.TRUE ) {
|
||||||
memberDetails.applyAnnotationUsage(
|
memberDetails.applyAnnotationUsage(
|
||||||
JpaAnnotations.ID,
|
JpaAnnotations.ID,
|
||||||
|
|
|
@ -2090,6 +2090,7 @@
|
||||||
type="orm:foreign-key"
|
type="orm:foreign-key"
|
||||||
minOccurs="0"/>
|
minOccurs="0"/>
|
||||||
</xsd:sequence>
|
</xsd:sequence>
|
||||||
|
<xsd:sequence>
|
||||||
<xsd:sequence>
|
<xsd:sequence>
|
||||||
<xsd:sequence>
|
<xsd:sequence>
|
||||||
<xsd:choice maxOccurs="unbounded">
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
@ -2098,6 +2099,8 @@
|
||||||
</xsd:choice>
|
</xsd:choice>
|
||||||
<xsd:element name="foreign-key" type="orm:foreign-key" minOccurs="0"/>
|
<xsd:element name="foreign-key" type="orm:foreign-key" minOccurs="0"/>
|
||||||
</xsd:sequence>
|
</xsd:sequence>
|
||||||
|
<xsd:element name="property-ref" type="orm:property-ref"/>
|
||||||
|
</xsd:sequence>
|
||||||
</xsd:sequence>
|
</xsd:sequence>
|
||||||
<xsd:element name="join-table" type="orm:join-table"
|
<xsd:element name="join-table" type="orm:join-table"
|
||||||
minOccurs="0"/>
|
minOccurs="0"/>
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* 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.foreigngenerator;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("JUnitMalformedDeclaration")
|
||||||
|
@DomainModel(annotatedClasses = {Thing.class, Info.class})
|
||||||
|
@SessionFactory
|
||||||
|
public class ForeignGeneratorTests {
|
||||||
|
@Test
|
||||||
|
void checkGeneration(SessionFactoryScope sessionFactoryScope) {
|
||||||
|
sessionFactoryScope.inTransaction( (session) -> {
|
||||||
|
final Thing thing = new Thing( 1, "thing-1" );
|
||||||
|
final Info info = new Info( thing, "info-1" );
|
||||||
|
thing.setInfo( info );
|
||||||
|
info.setOwner( thing );
|
||||||
|
session.persist( thing );
|
||||||
|
session.persist( info );
|
||||||
|
} );
|
||||||
|
|
||||||
|
sessionFactoryScope.inTransaction( (session) -> {
|
||||||
|
final Thing thing = session.find( Thing.class, 1 );
|
||||||
|
assertThat( thing.getId() ).isEqualTo( thing.getInfo().getId() );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
void tearDown(SessionFactoryScope sessionFactoryScope) {
|
||||||
|
sessionFactoryScope.inTransaction( (session) -> {
|
||||||
|
session.createMutationQuery( "delete Info" ).executeUpdate();
|
||||||
|
session.createMutationQuery( "delete Thing" ).executeUpdate();
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* 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.foreigngenerator;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.GenericGenerator;
|
||||||
|
import org.hibernate.annotations.Parameter;
|
||||||
|
import org.hibernate.id.ForeignGenerator;
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.Basic;
|
||||||
|
import jakarta.persistence.ManyToOne;
|
||||||
|
import jakarta.persistence.OneToOne;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
public class Info {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue( generator = "foreign" )
|
||||||
|
@GenericGenerator(
|
||||||
|
name = "foreign",
|
||||||
|
type = ForeignGenerator.class,
|
||||||
|
parameters = @Parameter( name = "property", value = "owner" )
|
||||||
|
)
|
||||||
|
private Integer id;
|
||||||
|
@Basic
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
private Thing owner;
|
||||||
|
|
||||||
|
protected Info() {
|
||||||
|
// for Hibernate use
|
||||||
|
}
|
||||||
|
|
||||||
|
public Info(Thing owner, String name) {
|
||||||
|
this.owner = owner;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Thing getOwner() {
|
||||||
|
return owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOwner(Thing owner) {
|
||||||
|
this.owner = owner;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* 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.foreigngenerator;
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.Basic;
|
||||||
|
import jakarta.persistence.OneToOne;
|
||||||
|
import jakarta.persistence.SequenceGenerator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
public class Thing {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
@Basic
|
||||||
|
private String name;
|
||||||
|
@OneToOne(mappedBy = "owner")
|
||||||
|
private Info info;
|
||||||
|
|
||||||
|
protected Thing() {
|
||||||
|
// for Hibernate use
|
||||||
|
}
|
||||||
|
|
||||||
|
public Thing(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Info getInfo() {
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInfo(Info info) {
|
||||||
|
this.info = info;
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,8 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.orm.test.boot.models.hbm.mappedsuper;
|
package org.hibernate.orm.test.boot.models.hbm.mappedsuper;
|
||||||
|
|
||||||
|
import org.hibernate.boot.Metadata;
|
||||||
|
import org.hibernate.boot.MetadataSources;
|
||||||
import org.hibernate.boot.spi.MetadataImplementor;
|
import org.hibernate.boot.spi.MetadataImplementor;
|
||||||
import org.hibernate.cfg.MappingSettings;
|
import org.hibernate.cfg.MappingSettings;
|
||||||
import org.hibernate.mapping.PersistentClass;
|
import org.hibernate.mapping.PersistentClass;
|
||||||
|
@ -15,6 +17,7 @@ import org.hibernate.testing.orm.junit.DomainModelScope;
|
||||||
import org.hibernate.testing.orm.junit.FailureExpected;
|
import org.hibernate.testing.orm.junit.FailureExpected;
|
||||||
import org.hibernate.testing.orm.junit.Jira;
|
import org.hibernate.testing.orm.junit.Jira;
|
||||||
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||||
|
import org.hibernate.testing.orm.junit.ServiceRegistryScope;
|
||||||
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;
|
||||||
|
|
||||||
|
@ -26,21 +29,23 @@ public class ImpliedMappedSuperTests {
|
||||||
@Test
|
@Test
|
||||||
@DomainModel( xmlMappings = "mappings/models/hbm/mappedsuper/implied-mapped-super.xml" )
|
@DomainModel( xmlMappings = "mappings/models/hbm/mappedsuper/implied-mapped-super.xml" )
|
||||||
void testHbm(DomainModelScope domainModelScope) {
|
void testHbm(DomainModelScope domainModelScope) {
|
||||||
verify( domainModelScope );
|
verify( domainModelScope.getDomainModel() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@FailureExpected( reason = "Support for implied mapped-superclass from hbm.xml is not implemented yet" )
|
@FailureExpected( reason = "Support for implied mapped-superclass from hbm.xml is not implemented yet" )
|
||||||
@Jira( "https://hibernate.atlassian.net/browse/HHH-18387" )
|
@Jira( "https://hibernate.atlassian.net/browse/HHH-18387" )
|
||||||
@ServiceRegistry( settings = @Setting( name = MappingSettings.TRANSFORM_HBM_XML, value = "true" ) )
|
@ServiceRegistry( settings = @Setting( name = MappingSettings.TRANSFORM_HBM_XML, value = "true" ) )
|
||||||
@DomainModel( xmlMappings = "mappings/models/hbm/mappedsuper/implied-mapped-super.xml" )
|
void testHbmTransformation(ServiceRegistryScope registryScope) {
|
||||||
void testHbmTransformation(DomainModelScope domainModelScope) {
|
final Metadata domainModel = new MetadataSources( registryScope.getRegistry() )
|
||||||
verify( domainModelScope );
|
.addResource( "mappings/models/hbm/mappedsuper/implied-mapped-super.xml" )
|
||||||
|
.buildMetadata();
|
||||||
|
verify( domainModel );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void verify(DomainModelScope domainModelScope) {
|
private void verify(Metadata domainModel) {
|
||||||
final PersistentClass thing1Binding = domainModelScope.getEntityBinding( Thing1.class );
|
final PersistentClass thing1Binding = domainModel.getEntityBinding( Thing1.class.getName() );
|
||||||
final PersistentClass thing2Binding = domainModelScope.getEntityBinding( Thing2.class );
|
final PersistentClass thing2Binding = domainModel.getEntityBinding( Thing2.class.getName() );
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,101 @@
|
||||||
|
/*
|
||||||
|
* 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.propertyref;
|
||||||
|
|
||||||
|
import java.io.StringWriter;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.PropertyRef;
|
||||||
|
import org.hibernate.cfg.MappingSettings;
|
||||||
|
import org.hibernate.internal.util.StringHelper;
|
||||||
|
|
||||||
|
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.ServiceRegistryScope;
|
||||||
|
import org.hibernate.testing.orm.junit.Setting;
|
||||||
|
import org.hibernate.testing.schema.SchemaCreateHelper;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.ManyToOne;
|
||||||
|
import jakarta.persistence.OneToOne;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("JUnitMalformedDeclaration")
|
||||||
|
@Jira( "https://hibernate.atlassian.net/browse/HHH-18396" )
|
||||||
|
public class ReferenceManyToOneTests {
|
||||||
|
@Test
|
||||||
|
@ServiceRegistry( settings = @Setting( name = MappingSettings.TRANSFORM_HBM_XML, value = "false" ) )
|
||||||
|
@DomainModel(xmlMappings = "mappings/models/hbm/propertyref/ref-one-to-one.hbm.xml")
|
||||||
|
void testHbm(ServiceRegistryScope registryScope, DomainModelScope domainModelScope) {
|
||||||
|
verifySchema( registryScope, domainModelScope );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@FailureExpected( reason = "Support for property-ref pointing to a to-one not yet implemented in annotations nor mapping.xml", jiraKey = "HHH-18396" )
|
||||||
|
@ServiceRegistry( settings = @Setting( name = MappingSettings.TRANSFORM_HBM_XML, value = "true" ) )
|
||||||
|
@DomainModel(xmlMappings = "mappings/models/hbm/propertyref/ref-one-to-one.hbm.xml")
|
||||||
|
void testHbmTransformed(ServiceRegistryScope registryScope, DomainModelScope domainModelScope) {
|
||||||
|
verifySchema( registryScope, domainModelScope );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@FailureExpected( reason = "Support for property-ref pointing to a to-one not yet implemented in annotations nor mapping.xml", jiraKey = "HHH-18396" )
|
||||||
|
@ServiceRegistry( settings = @Setting( name = MappingSettings.TRANSFORM_HBM_XML, value = "false" ) )
|
||||||
|
@DomainModel( annotatedClasses = {Thing.class, Info.class} )
|
||||||
|
void testAnnotations(ServiceRegistryScope registryScope, DomainModelScope domainModelScope) {
|
||||||
|
verifySchema( registryScope, domainModelScope );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifySchema(ServiceRegistryScope registryScope, DomainModelScope domainModelScope) {
|
||||||
|
final String schemaScript = toSchemaScript( registryScope, domainModelScope );
|
||||||
|
assertThat( schemaScript ).doesNotContainIgnoringCase( "owner_id", "info_id" );
|
||||||
|
assertThat( StringHelper.count( schemaScript, "foreign key (" ) ).isEqualTo( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
private String toSchemaScript(ServiceRegistryScope registryScope, DomainModelScope domainModelScope) {
|
||||||
|
final StringWriter stringWriter = new StringWriter();
|
||||||
|
SchemaCreateHelper.createOnlyToWriter( domainModelScope.getDomainModel(), registryScope.getRegistry(), stringWriter );
|
||||||
|
|
||||||
|
System.out.println( "Schema" );
|
||||||
|
System.out.println( "------" );
|
||||||
|
System.out.println( stringWriter );
|
||||||
|
|
||||||
|
return stringWriter.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name="Thing")
|
||||||
|
@Table(name="things")
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public static class Thing {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
private String name;
|
||||||
|
@OneToOne
|
||||||
|
@PropertyRef( "owner" )
|
||||||
|
private Info info;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name="Info")
|
||||||
|
@Table(name="infos")
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public static class Info {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
private String name;
|
||||||
|
@ManyToOne
|
||||||
|
private Thing owner;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,105 @@
|
||||||
|
/*
|
||||||
|
* 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.propertyref;
|
||||||
|
|
||||||
|
import java.io.StringWriter;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.PropertyRef;
|
||||||
|
import org.hibernate.cfg.MappingSettings;
|
||||||
|
import org.hibernate.dialect.H2Dialect;
|
||||||
|
import org.hibernate.internal.util.StringHelper;
|
||||||
|
|
||||||
|
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.RequiresDialect;
|
||||||
|
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||||
|
import org.hibernate.testing.orm.junit.ServiceRegistryScope;
|
||||||
|
import org.hibernate.testing.orm.junit.Setting;
|
||||||
|
import org.hibernate.testing.schema.SchemaCreateHelper;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.OneToOne;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @implNote Limited to H2 as the dialect is irrelevant and allows us to assert specific, expected syntax
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("JUnitMalformedDeclaration")
|
||||||
|
@Jira( "https://hibernate.atlassian.net/browse/HHH-18396" )
|
||||||
|
@RequiresDialect( H2Dialect.class )
|
||||||
|
public class ReferenceOneToOneTests {
|
||||||
|
@Test
|
||||||
|
@ServiceRegistry( settings = @Setting( name = MappingSettings.TRANSFORM_HBM_XML, value = "false" ) )
|
||||||
|
@DomainModel(xmlMappings = "mappings/models/hbm/propertyref/ref-one-to-one.hbm.xml")
|
||||||
|
void testHbm(ServiceRegistryScope registryScope, DomainModelScope domainModelScope) {
|
||||||
|
verifySchema( registryScope, domainModelScope );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@FailureExpected( reason = "Support for property-ref pointing to a to-one not yet implemented in annotations nor mapping.xml", jiraKey = "HHH-18396" )
|
||||||
|
@ServiceRegistry( settings = @Setting( name = MappingSettings.TRANSFORM_HBM_XML, value = "true" ) )
|
||||||
|
@DomainModel(xmlMappings = "mappings/models/hbm/propertyref/ref-one-to-one.hbm.xml")
|
||||||
|
void testHbmTransformed(ServiceRegistryScope registryScope, DomainModelScope domainModelScope) {
|
||||||
|
verifySchema( registryScope, domainModelScope );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@FailureExpected( reason = "Support for property-ref pointing to a to-one not yet implemented in annotations nor mapping.xml", jiraKey = "HHH-18396" )
|
||||||
|
@ServiceRegistry( settings = @Setting( name = MappingSettings.TRANSFORM_HBM_XML, value = "false" ) )
|
||||||
|
@DomainModel( annotatedClasses = {Thing.class, Info.class} )
|
||||||
|
void testAnnotations(ServiceRegistryScope registryScope, DomainModelScope domainModelScope) {
|
||||||
|
verifySchema( registryScope, domainModelScope );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifySchema(ServiceRegistryScope registryScope, DomainModelScope domainModelScope) {
|
||||||
|
final String schemaScript = toSchemaScript( registryScope, domainModelScope );
|
||||||
|
assertThat( schemaScript ).doesNotContainIgnoringCase( "owner_id", "info_id" );
|
||||||
|
assertThat( StringHelper.count( schemaScript, "foreign key (" ) ).isEqualTo( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
private String toSchemaScript(ServiceRegistryScope registryScope, DomainModelScope domainModelScope) {
|
||||||
|
final StringWriter stringWriter = new StringWriter();
|
||||||
|
SchemaCreateHelper.createOnlyToWriter( domainModelScope.getDomainModel(), registryScope.getRegistry(), stringWriter );
|
||||||
|
|
||||||
|
System.out.println( "Schema" );
|
||||||
|
System.out.println( "------" );
|
||||||
|
System.out.println( stringWriter );
|
||||||
|
|
||||||
|
return stringWriter.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name="Thing")
|
||||||
|
@Table(name="things")
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public static class Thing {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
private String name;
|
||||||
|
@OneToOne
|
||||||
|
@PropertyRef( "owner" )
|
||||||
|
private Info info;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name="Info")
|
||||||
|
@Table(name="infos")
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public static class Info {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
private String name;
|
||||||
|
@OneToOne
|
||||||
|
private Thing owner;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?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.propertyref" default-access="field">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
property-ref pointing to a many-to-one
|
||||||
|
-->
|
||||||
|
<class name="ReferenceManyToOneTests$Thing" table="things">
|
||||||
|
<id name="id" column="id" type="long">
|
||||||
|
<generator class="increment"/>
|
||||||
|
</id>
|
||||||
|
<property name="name" type="string" unique="true"/>
|
||||||
|
<one-to-one name="info" property-ref="owner" class="ReferenceManyToOneTests$ParentInfo" cascade="none"/>
|
||||||
|
</class>
|
||||||
|
|
||||||
|
<class name="ReferenceManyToOneTests$Info" table="infos">
|
||||||
|
<id name="id" column="id" type="long">
|
||||||
|
<generator class="increment"/>
|
||||||
|
</id>
|
||||||
|
<property name="name" type="string" unique="true"/>
|
||||||
|
<many-to-one name="owner" class="ReferenceManyToOneTests$Thing" cascade="none"/>
|
||||||
|
</class>
|
||||||
|
|
||||||
|
</hibernate-mapping>
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?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.propertyref" default-access="field">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
property-ref pointing to a one-to-one
|
||||||
|
-->
|
||||||
|
<class name="ReferenceOneToOneTests$Thing" table="things">
|
||||||
|
<id name="id" column="id" type="long">
|
||||||
|
<generator class="increment"/>
|
||||||
|
</id>
|
||||||
|
<property name="name" type="string" unique="true"/>
|
||||||
|
<one-to-one name="info" property-ref="owner" class="ReferenceOneToOneTests$Info" cascade="none"/>
|
||||||
|
</class>
|
||||||
|
|
||||||
|
<class name="ReferenceOneToOneTests$Info" table="infos">
|
||||||
|
<id name="id" column="id" type="long">
|
||||||
|
<generator class="increment"/>
|
||||||
|
</id>
|
||||||
|
<property name="name" type="string" unique="true"/>
|
||||||
|
<one-to-one name="owner" class="ReferenceOneToOneTests$Thing" constrained="true" cascade="none"/>
|
||||||
|
</class>
|
||||||
|
|
||||||
|
</hibernate-mapping>
|
|
@ -9,12 +9,14 @@ package org.hibernate.testing.schema;
|
||||||
import java.io.OutputStreamWriter;
|
import java.io.OutputStreamWriter;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.hibernate.boot.Metadata;
|
import org.hibernate.boot.Metadata;
|
||||||
import org.hibernate.boot.registry.StandardServiceRegistry;
|
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||||
import org.hibernate.boot.spi.MetadataImplementor;
|
import org.hibernate.boot.spi.MetadataImplementor;
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
import org.hibernate.cfg.SchemaToolingSettings;
|
||||||
import org.hibernate.engine.config.spi.ConfigurationService;
|
import org.hibernate.engine.config.spi.ConfigurationService;
|
||||||
import org.hibernate.internal.build.AllowSysOut;
|
import org.hibernate.internal.build.AllowSysOut;
|
||||||
import org.hibernate.service.ServiceRegistry;
|
import org.hibernate.service.ServiceRegistry;
|
||||||
|
@ -44,17 +46,6 @@ public class SchemaCreateHelper {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void createOnly(Metadata metadata, ServiceRegistry serviceRegistry) {
|
|
||||||
final Map settings = serviceRegistry.getService( ConfigurationService.class ).getSettings();
|
|
||||||
settings.put( AvailableSettings.JAKARTA_HBM2DDL_DATABASE_ACTION, Action.CREATE_ONLY );
|
|
||||||
SchemaManagementToolCoordinator.process(
|
|
||||||
metadata,
|
|
||||||
serviceRegistry,
|
|
||||||
settings,
|
|
||||||
DelayedDropRegistryNotAvailableImpl.INSTANCE
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void create(
|
public static void create(
|
||||||
Metadata metadata,
|
Metadata metadata,
|
||||||
StandardServiceRegistry serviceRegistry,
|
StandardServiceRegistry serviceRegistry,
|
||||||
|
@ -77,13 +68,31 @@ public class SchemaCreateHelper {
|
||||||
|
|
||||||
public static void toWriter(Metadata metadata, Writer writer) {
|
public static void toWriter(Metadata metadata, Writer writer) {
|
||||||
final ServiceRegistry serviceRegistry = ( (MetadataImplementor) metadata ).getMetadataBuildingOptions().getServiceRegistry();
|
final ServiceRegistry serviceRegistry = ( (MetadataImplementor) metadata ).getMetadataBuildingOptions().getServiceRegistry();
|
||||||
final Map settings = serviceRegistry.getService( ConfigurationService.class ).getSettings();
|
final Map<String,Object> settings = serviceRegistry.requireService( ConfigurationService.class ).getSettings();
|
||||||
settings.put( AvailableSettings.HBM2DDL_SCRIPTS_ACTION, Action.CREATE );
|
final Map<String,Object> copy = new HashMap<>( settings );
|
||||||
settings.put( AvailableSettings.HBM2DDL_SCRIPTS_CREATE_TARGET, writer );
|
copy.put( SchemaToolingSettings.JAKARTA_HBM2DDL_SCRIPTS_ACTION, Action.CREATE );
|
||||||
|
copy.put( SchemaToolingSettings.JAKARTA_HBM2DDL_SCRIPTS_CREATE_TARGET, writer );
|
||||||
SchemaManagementToolCoordinator.process(
|
SchemaManagementToolCoordinator.process(
|
||||||
metadata,
|
metadata,
|
||||||
serviceRegistry,
|
serviceRegistry,
|
||||||
settings,
|
copy,
|
||||||
|
DelayedDropRegistryNotAvailableImpl.INSTANCE
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void createOnlyToStdOut(Metadata metadata, ServiceRegistry serviceRegistry) {
|
||||||
|
createOnlyToWriter( metadata, serviceRegistry, new OutputStreamWriter( System.out ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void createOnlyToWriter(Metadata metadata, ServiceRegistry serviceRegistry, Writer target) {
|
||||||
|
final Map<String,Object> settings = serviceRegistry.requireService( ConfigurationService.class ).getSettings();
|
||||||
|
final Map<String,Object> copy = new HashMap<>( settings );
|
||||||
|
copy.put( SchemaToolingSettings.JAKARTA_HBM2DDL_SCRIPTS_ACTION, Action.CREATE_ONLY );
|
||||||
|
copy.put( SchemaToolingSettings.JAKARTA_HBM2DDL_SCRIPTS_CREATE_TARGET, target );
|
||||||
|
SchemaManagementToolCoordinator.process(
|
||||||
|
metadata,
|
||||||
|
serviceRegistry,
|
||||||
|
copy,
|
||||||
DelayedDropRegistryNotAvailableImpl.INSTANCE
|
DelayedDropRegistryNotAvailableImpl.INSTANCE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue