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,
|
||||
ColumnDefaults columnDefaults,
|
||||
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 ) {
|
||||
target.addFormula( formula.getFormula() );
|
||||
}
|
||||
|
@ -1181,12 +1182,18 @@ public class HbmXmlTransformer {
|
|||
final TargetColumnAdapter targetColumnAdapter = target.makeColumnAdapter( columnDefaults );
|
||||
targetColumnAdapter.setName( column.getQuotedName() );
|
||||
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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Integer convertColumnLength(Long length) {
|
||||
return length == null ? null : length.intValue();
|
||||
}
|
||||
|
||||
private void transferColumnsAndFormulas(
|
||||
ColumnAndFormulaSource source,
|
||||
ColumnAndFormulaTarget target,
|
||||
|
@ -1709,10 +1716,9 @@ public class HbmXmlTransformer {
|
|||
oneToOne.setOrphanRemoval( isOrphanRemoval( hbmOneToOne.getCascade() ) );
|
||||
oneToOne.setForeignKey( new JaxbForeignKeyImpl() );
|
||||
oneToOne.getForeignKey().setName( hbmOneToOne.getForeignKey() );
|
||||
if (! StringHelper.isEmpty( hbmOneToOne.getPropertyRef() ) ) {
|
||||
final JaxbJoinColumnImpl joinColumn = new JaxbJoinColumnImpl();
|
||||
joinColumn.setReferencedColumnName( hbmOneToOne.getPropertyRef() );
|
||||
oneToOne.getJoinColumnOrJoinFormula().add( joinColumn );
|
||||
if ( StringHelper.isNotEmpty( hbmOneToOne.getPropertyRef() ) ) {
|
||||
oneToOne.setPropertyRef( new JaxbPropertyRefImpl() );
|
||||
oneToOne.getPropertyRef().setName( hbmOneToOne.getPropertyRef() );
|
||||
}
|
||||
for ( String formula : hbmOneToOne.getFormula() ) {
|
||||
oneToOne.getJoinColumnOrJoinFormula().add( formula );
|
||||
|
@ -1780,7 +1786,7 @@ public class HbmXmlTransformer {
|
|||
jaxbManyToOne.getJoinColumnOrJoinFormula().add( formula );
|
||||
}
|
||||
},
|
||||
ColumnDefaultsBasicImpl.INSTANCE,
|
||||
new ColumnDefaultsProperty( manyToOneProperty ),
|
||||
propertyInfo.tableName()
|
||||
);
|
||||
|
||||
|
@ -3001,7 +3007,7 @@ public class HbmXmlTransformer {
|
|||
hbmCompositeId.getKeyPropertyOrKeyManyToOne().forEach( (hbmIdProperty) -> {
|
||||
if ( hbmIdProperty instanceof JaxbHbmCompositeKeyBasicAttributeType hbmKeyProperty ) {
|
||||
final PropertyInfo keyPropertyInfo = componentTypeInfo.propertyInfoMap().get( hbmKeyProperty.getName() );
|
||||
mappingXmlEntity.getAttributes().getIdAttributes().add( transformNonAggregatedIdProperty(
|
||||
mappingXmlEntity.getAttributes().getIdAttributes().add( transformNonAggregatedKeyProperty(
|
||||
hbmKeyProperty,
|
||||
keyPropertyInfo
|
||||
) );
|
||||
|
@ -3022,7 +3028,7 @@ public class HbmXmlTransformer {
|
|||
throw new UnsupportedOperationException( "Not implemented yet" );
|
||||
}
|
||||
|
||||
private JaxbIdImpl transformNonAggregatedIdProperty(
|
||||
private JaxbIdImpl transformNonAggregatedKeyProperty(
|
||||
JaxbHbmCompositeKeyBasicAttributeType hbmIdProperty,
|
||||
PropertyInfo idPropertyInfo) {
|
||||
final JaxbIdImpl jaxbBasic = new JaxbIdImpl();
|
||||
|
@ -3058,7 +3064,8 @@ public class HbmXmlTransformer {
|
|||
|
||||
@Override
|
||||
public List<Serializable> getColumnOrFormula() {
|
||||
return Collections.emptyList();
|
||||
//noinspection unchecked,rawtypes
|
||||
return (List) hbmIdProperty.getColumn();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -7,9 +7,11 @@
|
|||
package org.hibernate.boot.models.xml.internal.attr;
|
||||
|
||||
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.XmlAnnotations;
|
||||
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.xml.internal.XmlProcessingHelper;
|
||||
import org.hibernate.boot.models.xml.internal.db.JoinColumnProcessing;
|
||||
|
@ -62,6 +64,14 @@ public class OneToOneAttributeProcessing {
|
|||
JoinColumnProcessing.applyJoinColumnsOrFormulas( jaxbOneToOne.getJoinColumnOrJoinFormula(), 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 ) {
|
||||
memberDetails.applyAnnotationUsage(
|
||||
JpaAnnotations.ID,
|
||||
|
|
|
@ -2090,6 +2090,7 @@
|
|||
type="orm:foreign-key"
|
||||
minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
<xsd:sequence>
|
||||
<xsd:sequence>
|
||||
<xsd:sequence>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
|
@ -2098,6 +2099,8 @@
|
|||
</xsd:choice>
|
||||
<xsd:element name="foreign-key" type="orm:foreign-key" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
<xsd:element name="property-ref" type="orm:property-ref"/>
|
||||
</xsd:sequence>
|
||||
</xsd:sequence>
|
||||
<xsd:element name="join-table" type="orm:join-table"
|
||||
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;
|
||||
|
||||
import org.hibernate.boot.Metadata;
|
||||
import org.hibernate.boot.MetadataSources;
|
||||
import org.hibernate.boot.spi.MetadataImplementor;
|
||||
import org.hibernate.cfg.MappingSettings;
|
||||
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.Jira;
|
||||
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||
import org.hibernate.testing.orm.junit.ServiceRegistryScope;
|
||||
import org.hibernate.testing.orm.junit.Setting;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
@ -26,21 +29,23 @@ public class ImpliedMappedSuperTests {
|
|||
@Test
|
||||
@DomainModel( xmlMappings = "mappings/models/hbm/mappedsuper/implied-mapped-super.xml" )
|
||||
void testHbm(DomainModelScope domainModelScope) {
|
||||
verify( domainModelScope );
|
||||
verify( domainModelScope.getDomainModel() );
|
||||
}
|
||||
|
||||
@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 );
|
||||
void testHbmTransformation(ServiceRegistryScope registryScope) {
|
||||
final Metadata domainModel = new MetadataSources( registryScope.getRegistry() )
|
||||
.addResource( "mappings/models/hbm/mappedsuper/implied-mapped-super.xml" )
|
||||
.buildMetadata();
|
||||
verify( domainModel );
|
||||
}
|
||||
|
||||
private void verify(DomainModelScope domainModelScope) {
|
||||
final PersistentClass thing1Binding = domainModelScope.getEntityBinding( Thing1.class );
|
||||
final PersistentClass thing2Binding = domainModelScope.getEntityBinding( Thing2.class );
|
||||
private void verify(Metadata domainModel) {
|
||||
final PersistentClass thing1Binding = domainModel.getEntityBinding( Thing1.class.getName() );
|
||||
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.Writer;
|
||||
import java.sql.Connection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.boot.Metadata;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||
import org.hibernate.boot.spi.MetadataImplementor;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.cfg.SchemaToolingSettings;
|
||||
import org.hibernate.engine.config.spi.ConfigurationService;
|
||||
import org.hibernate.internal.build.AllowSysOut;
|
||||
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(
|
||||
Metadata metadata,
|
||||
StandardServiceRegistry serviceRegistry,
|
||||
|
@ -77,13 +68,31 @@ public class SchemaCreateHelper {
|
|||
|
||||
public static void toWriter(Metadata metadata, Writer writer) {
|
||||
final ServiceRegistry serviceRegistry = ( (MetadataImplementor) metadata ).getMetadataBuildingOptions().getServiceRegistry();
|
||||
final Map settings = serviceRegistry.getService( ConfigurationService.class ).getSettings();
|
||||
settings.put( AvailableSettings.HBM2DDL_SCRIPTS_ACTION, Action.CREATE );
|
||||
settings.put( AvailableSettings.HBM2DDL_SCRIPTS_CREATE_TARGET, writer );
|
||||
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 );
|
||||
copy.put( SchemaToolingSettings.JAKARTA_HBM2DDL_SCRIPTS_CREATE_TARGET, writer );
|
||||
SchemaManagementToolCoordinator.process(
|
||||
metadata,
|
||||
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
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue