HHH-14063 - AccessType is not correctly propagated for embeddable mappings in element-collection
- tests
This commit is contained in:
parent
4ddf6e39b5
commit
d5a23a61ea
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* 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.mapping.access;
|
||||
|
||||
import org.hibernate.mapping.BasicValue;
|
||||
import org.hibernate.mapping.Collection;
|
||||
import org.hibernate.mapping.Component;
|
||||
import org.hibernate.mapping.Property;
|
||||
import org.hibernate.metamodel.RuntimeMetamodels;
|
||||
import org.hibernate.metamodel.mapping.AttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.internal.EmbeddedAttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.internal.EmbeddedCollectionPart;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.DomainModelScope;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@DomainModel( annotatedClasses = { Person2.class, Name2.class } )
|
||||
@SessionFactory( exportSchema = false )
|
||||
public class EmbeddableDefaultAccessTests {
|
||||
@Test
|
||||
public void verifyBootModel(DomainModelScope scope) {
|
||||
scope.withHierarchy( Person2.class, (personDescriptor) -> {
|
||||
final Property nameProperty = personDescriptor.getProperty( "name" );
|
||||
final Component nameMapping = (Component) nameProperty.getValue();
|
||||
assertThat( nameMapping.getPropertySpan() ).isEqualTo( 2 );
|
||||
final Property nameFirst = nameMapping.getProperty( 0 );
|
||||
final Property nameLast = nameMapping.getProperty( 1 );
|
||||
assertThat( nameFirst.getName() ).isEqualTo( "first" );
|
||||
assertThat( nameLast.getName() ).isEqualTo( "last" );
|
||||
assertThat( ( (BasicValue) nameFirst.getValue() ).getColumn().getText() ).isEqualTo( "first_name" );
|
||||
assertThat( ( (BasicValue) nameLast.getValue() ).getColumn().getText() ).isEqualTo( "last_name" );
|
||||
assertThat( ( (BasicValue) nameFirst.getValue() ).getJpaAttributeConverterDescriptor() ).isNotNull();
|
||||
|
||||
final Property aliasesProperty = personDescriptor.getProperty( "aliases" );
|
||||
final Component aliasMapping = (Component) ( (Collection) aliasesProperty.getValue() ).getElement();
|
||||
assertThat( aliasMapping.getPropertySpan() ).isEqualTo( 2 );
|
||||
final Property aliasFirst = aliasMapping.getProperty( 0 );
|
||||
final Property aliasLast = aliasMapping.getProperty( 1 );
|
||||
assertThat( aliasFirst.getName() ).isEqualTo( "first" );
|
||||
assertThat( aliasLast.getName() ).isEqualTo( "last" );
|
||||
assertThat( ( (BasicValue) aliasFirst.getValue() ).getColumn().getText() ).isEqualTo( "first_name" );
|
||||
assertThat( ( (BasicValue) aliasLast.getValue() ).getColumn().getText() ).isEqualTo( "last_name" );
|
||||
assertThat( ( (BasicValue) aliasFirst.getValue() ).getJpaAttributeConverterDescriptor() ).isNotNull();
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verifyRuntimeModel(SessionFactoryScope scope) {
|
||||
final RuntimeMetamodels runtimeMetamodels = scope.getSessionFactory().getRuntimeMetamodels();
|
||||
final EntityMappingType personDescriptor = runtimeMetamodels.getEntityMappingType( Person2.class );
|
||||
|
||||
// Person defines FIELD access, while Name uses PROPERTY
|
||||
// - if we find the property annotations, the attribute names will be
|
||||
// `firstName` and `lastName`, and the columns `first_name` and `last_name`
|
||||
// - otherwise, we have property and column names being `first` and `last`
|
||||
final EmbeddableMappingType nameEmbeddable = ( (EmbeddedAttributeMapping) personDescriptor.findAttributeMapping( "name" ) ).getEmbeddableTypeDescriptor();
|
||||
assertThat( nameEmbeddable.getNumberOfAttributeMappings() ).isEqualTo( 2 );
|
||||
final AttributeMapping nameFirst = nameEmbeddable.getAttributeMapping( 0 );
|
||||
final AttributeMapping nameLast = nameEmbeddable.getAttributeMapping( 1 );
|
||||
assertThat( nameFirst.getAttributeName() ).isEqualTo( "first" );
|
||||
assertThat( nameLast.getAttributeName() ).isEqualTo( "last" );
|
||||
|
||||
final PluralAttributeMapping aliasesAttribute = (PluralAttributeMapping) personDescriptor.findAttributeMapping( "aliases" );
|
||||
final EmbeddableMappingType aliasEmbeddable = ( (EmbeddedCollectionPart) aliasesAttribute.getElementDescriptor() ).getEmbeddableTypeDescriptor();
|
||||
assertThat( aliasEmbeddable.getNumberOfAttributeMappings() ).isEqualTo( 2 );
|
||||
final AttributeMapping aliasFirst = nameEmbeddable.getAttributeMapping( 0 );
|
||||
final AttributeMapping aliasLast = nameEmbeddable.getAttributeMapping( 1 );
|
||||
assertThat( aliasFirst.getAttributeName() ).isEqualTo( "first" );
|
||||
assertThat( aliasLast.getAttributeName() ).isEqualTo( "last" );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* 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.mapping.access;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Convert;
|
||||
import jakarta.persistence.Embeddable;
|
||||
|
||||
@Embeddable
|
||||
public class Name2 {
|
||||
@Column(name = "first_name")
|
||||
@Convert( converter = SillyConverter.class )
|
||||
private String first;
|
||||
@Column(name = "last_name")
|
||||
private String last;
|
||||
|
||||
private Name2() {
|
||||
}
|
||||
|
||||
public Name2(String first, String last) {
|
||||
this.first = first;
|
||||
this.last = last;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return first;
|
||||
}
|
||||
|
||||
public void setFirstName(String first) {
|
||||
this.first = first;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return last;
|
||||
}
|
||||
|
||||
public void setLastName(String last) {
|
||||
this.last = last;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
* 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.mapping.access;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.mapping.BasicValue;
|
||||
import org.hibernate.mapping.Collection;
|
||||
import org.hibernate.mapping.Component;
|
||||
import org.hibernate.mapping.Property;
|
||||
|
||||
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.SessionFactory;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jakarta.persistence.Basic;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Convert;
|
||||
import jakarta.persistence.ElementCollection;
|
||||
import jakarta.persistence.Embeddable;
|
||||
import jakarta.persistence.Embedded;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@DomainModel( annotatedClasses = { NestedEmbeddableDefaultAccessTests.MyEntity.class } )
|
||||
@SessionFactory( exportSchema = false )
|
||||
public class NestedEmbeddableDefaultAccessTests {
|
||||
@Test
|
||||
public void verifyEmbeddedMapping(DomainModelScope scope) {
|
||||
scope.withHierarchy( MyEntity.class, (descriptor) -> {
|
||||
final Property outerEmbedded = descriptor.getProperty( "outerEmbeddable" );
|
||||
verifyMapping( (Component) outerEmbedded.getValue() );
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
@Jira( "https://hibernate.atlassian.net/browse/HHH-14063" )
|
||||
@FailureExpected(
|
||||
reason = "When an embeddable is a key or element of a collection, access-type is " +
|
||||
"not properly propagated to nested embeddables"
|
||||
)
|
||||
public void verifyElementCollectionMapping(DomainModelScope scope) {
|
||||
scope.withHierarchy( MyEntity.class, (descriptor) -> {
|
||||
final Property outerEmbeddedList = descriptor.getProperty( "outerEmbeddableList" );
|
||||
verifyMapping( (Component) ( (Collection) outerEmbeddedList.getValue() ).getElement() );
|
||||
} );
|
||||
}
|
||||
|
||||
private void verifyMapping(Component outerEmbeddable) {
|
||||
final Property outerData = outerEmbeddable.getProperty( "outerData" );
|
||||
final BasicValue outerDataMapping = (BasicValue) outerData.getValue();
|
||||
final Property nestedEmbedded = outerEmbeddable.getProperty( "nestedEmbeddable" );
|
||||
final Component nestedEmbeddable = (Component) nestedEmbedded.getValue();
|
||||
final Property nestedData = nestedEmbeddable.getProperty( "nestedData" );
|
||||
final BasicValue nestedDataMapping = (BasicValue) nestedData.getValue();
|
||||
|
||||
assertThat( outerDataMapping.getColumn().getText() ).isEqualTo( "outer_data" );
|
||||
assertThat( outerDataMapping.getJpaAttributeConverterDescriptor() ).isNotNull();
|
||||
|
||||
assertThat( nestedDataMapping.getColumn().getText() ).isEqualTo( "nested_data" );
|
||||
}
|
||||
|
||||
@Entity( name = "MyEntity" )
|
||||
@Table( name = "MyEntity" )
|
||||
public static class MyEntity {
|
||||
@Id
|
||||
private Integer id;
|
||||
@Basic
|
||||
private String name;
|
||||
@Embedded
|
||||
private OuterEmbeddable outerEmbeddable;
|
||||
@ElementCollection
|
||||
private List<OuterEmbeddable> outerEmbeddableList;
|
||||
|
||||
private MyEntity() {
|
||||
// for use by Hibernate
|
||||
}
|
||||
|
||||
public MyEntity(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 OuterEmbeddable getOuterEmbeddable() {
|
||||
return outerEmbeddable;
|
||||
}
|
||||
|
||||
public void setOuterEmbeddable(OuterEmbeddable outerEmbeddable) {
|
||||
this.outerEmbeddable = outerEmbeddable;
|
||||
}
|
||||
}
|
||||
|
||||
@Embeddable
|
||||
public static class OuterEmbeddable {
|
||||
@Convert( converter = SillyConverter.class )
|
||||
@Column( name = "outer_data" )
|
||||
private String outerData;
|
||||
|
||||
@Embedded
|
||||
private NestedEmbeddable nestedEmbeddable;
|
||||
}
|
||||
|
||||
@Embeddable
|
||||
public static class NestedEmbeddable {
|
||||
@Convert( converter = SillyConverter.class )
|
||||
@Column( name = "nested_data" )
|
||||
private String nestedData;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* 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.mapping.access;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import jakarta.persistence.CollectionTable;
|
||||
import jakarta.persistence.ElementCollection;
|
||||
import jakarta.persistence.Embedded;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "persons2")
|
||||
public class Person2 {
|
||||
@Id
|
||||
public Integer id;
|
||||
|
||||
@Embedded
|
||||
public Name2 name;
|
||||
|
||||
@ElementCollection
|
||||
@CollectionTable( name = "person2_aliases" )
|
||||
@Embedded
|
||||
public Set<Name2> aliases;
|
||||
|
||||
private Person2() {
|
||||
// for Hibernate use
|
||||
}
|
||||
|
||||
public Person2(Integer id, Name2 name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public Name2 getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(Name2 name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Set<Name2> getAliases() {
|
||||
return aliases;
|
||||
}
|
||||
|
||||
public void setAliases(Set<Name2> aliases) {
|
||||
this.aliases = aliases;
|
||||
}
|
||||
|
||||
public void addAlias(Name2 alias) {
|
||||
if ( aliases == null ) {
|
||||
aliases = new HashSet<>();
|
||||
}
|
||||
aliases.add( alias );
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* 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.mapping.access;
|
||||
|
||||
import jakarta.persistence.AttributeConverter;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class SillyConverter implements AttributeConverter<String, String> {
|
||||
@Override
|
||||
public String convertToDatabaseColumn(String attribute) {
|
||||
return attribute;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String convertToEntityAttribute(String dbData) {
|
||||
return dbData;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue