mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-02-08 12:14:47 +00:00
HHH-14467 Test referencing an entity whose ID is derived
Signed-off-by: Yoann Rodière <yoann@hibernate.org>
This commit is contained in:
parent
27ceeedc04
commit
3f422304e7
@ -0,0 +1,273 @@
|
||||
/*
|
||||
* 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.test.annotations.derivedidentities.e4.c;
|
||||
|
||||
import java.io.Serializable;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.OneToOne;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hibernate.test.util.SchemaUtil.getColumnNames;
|
||||
|
||||
/**
|
||||
* Test that when an entity with derived identity is referenced from a third entity,
|
||||
* associations on that third entity are bound in a second pass *after* the derived identity is bound.
|
||||
*
|
||||
* This test used to fail on bootstrap with the following error:
|
||||
*
|
||||
* org.hibernate.MappingException: Foreign key (FK2m2b1kaetxfvcsaih4raaocn8:ref_mto_derived [])) must have same number of columns as the referenced primary key (mto_derived [idsource_id])
|
||||
*/
|
||||
@TestForIssue(jiraKey = "HHH-14467")
|
||||
public class DerivedIdentitySimpleParentSimpleDepSecondPassOrderingTest extends BaseNonConfigCoreFunctionalTestCase {
|
||||
@Test
|
||||
public void testOneToOne() {
|
||||
assertThat( getColumnNames( "oto_derived", metadata() ) )
|
||||
.contains( "idsource_id" )
|
||||
.doesNotContain( "id", "idSource", "idsource" );
|
||||
|
||||
inTransaction( s -> {
|
||||
EntityWithSimpleId simple = new EntityWithSimpleId( 1 );
|
||||
s.persist( simple );
|
||||
EntityWithOneToOneDerivedId derived = new EntityWithOneToOneDerivedId( simple );
|
||||
s.persist( derived );
|
||||
} );
|
||||
|
||||
inTransaction( s -> {
|
||||
EntityWithOneToOneDerivedId derived = s.get( EntityWithOneToOneDerivedId.class, 1 );
|
||||
assertThat( derived.getIdsource().getId() ).isEqualTo( 1 );
|
||||
derived.setData( "something" );
|
||||
} );
|
||||
|
||||
inTransaction( s -> {
|
||||
EntityWithOneToOneDerivedId derived = s.get( EntityWithOneToOneDerivedId.class, 1 );
|
||||
assertThat( derived.getData() ).isNotNull();
|
||||
} );
|
||||
|
||||
inTransaction( s -> {
|
||||
EntityWithOneToOneDerivedId derived = s.get( EntityWithOneToOneDerivedId.class, 1 );
|
||||
EntityReferencingEntityWithOneToOneDerivedId referencing =
|
||||
new EntityReferencingEntityWithOneToOneDerivedId( 1, derived );
|
||||
s.persist( referencing );
|
||||
} );
|
||||
|
||||
inTransaction( s -> {
|
||||
EntityReferencingEntityWithOneToOneDerivedId referencing =
|
||||
s.get( EntityReferencingEntityWithOneToOneDerivedId.class, 1 );
|
||||
assertThat( referencing.getRef().getIdsource().getId() ).isEqualTo( 1 );
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testManyToOne() {
|
||||
assertThat( getColumnNames( "mto_derived", metadata() ) )
|
||||
.contains( "idsource_id" )
|
||||
.doesNotContain( "id", "idSource", "idsource" );
|
||||
|
||||
inTransaction( s -> {
|
||||
EntityWithSimpleId simple = new EntityWithSimpleId( 2 );
|
||||
s.persist( simple );
|
||||
EntityWithManyToOneDerivedId derived = new EntityWithManyToOneDerivedId( simple );
|
||||
s.persist( derived );
|
||||
} );
|
||||
|
||||
inTransaction( s -> {
|
||||
EntityWithManyToOneDerivedId derived = s.get( EntityWithManyToOneDerivedId.class, 2 );
|
||||
assertThat( derived.getIdsource().getId() ).isEqualTo( 2 );
|
||||
derived.setData( "something" );
|
||||
} );
|
||||
|
||||
inTransaction( s -> {
|
||||
EntityWithManyToOneDerivedId derived = s.get( EntityWithManyToOneDerivedId.class, 2 );
|
||||
assertThat( derived.getData() ).isNotNull();
|
||||
} );
|
||||
|
||||
inTransaction( s -> {
|
||||
EntityWithManyToOneDerivedId derived = s.get( EntityWithManyToOneDerivedId.class, 2 );
|
||||
EntityReferencingEntityWithManyToOneDerivedId referencing =
|
||||
new EntityReferencingEntityWithManyToOneDerivedId( 2, derived );
|
||||
s.persist( referencing );
|
||||
} );
|
||||
|
||||
inTransaction( s -> {
|
||||
EntityReferencingEntityWithManyToOneDerivedId referencing =
|
||||
s.get( EntityReferencingEntityWithManyToOneDerivedId.class, 2 );
|
||||
assertThat( referencing.getRef().getIdsource().getId() ).isEqualTo( 2 );
|
||||
} );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class<?>[] {
|
||||
// These two must be mentioned first in order to trigger the bug.
|
||||
// In a real application this would happen randomly, depending on how JARs are scanned.
|
||||
EntityReferencingEntityWithOneToOneDerivedId.class,
|
||||
EntityReferencingEntityWithManyToOneDerivedId.class,
|
||||
|
||||
EntityWithSimpleId.class,
|
||||
EntityWithOneToOneDerivedId.class,
|
||||
EntityWithManyToOneDerivedId.class
|
||||
};
|
||||
}
|
||||
|
||||
@Entity(name = "simple")
|
||||
public static class EntityWithSimpleId {
|
||||
@Id
|
||||
private Integer id;
|
||||
|
||||
public EntityWithSimpleId() {
|
||||
}
|
||||
|
||||
public EntityWithSimpleId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
||||
@Entity(name = "oto_derived")
|
||||
public static class EntityWithOneToOneDerivedId implements Serializable {
|
||||
@Id
|
||||
@OneToOne
|
||||
private EntityWithSimpleId idsource;
|
||||
|
||||
private String data;
|
||||
|
||||
public EntityWithOneToOneDerivedId() {
|
||||
}
|
||||
|
||||
public EntityWithOneToOneDerivedId(EntityWithSimpleId idsource) {
|
||||
this.idsource = idsource;
|
||||
}
|
||||
|
||||
public EntityWithSimpleId getIdsource() {
|
||||
return idsource;
|
||||
}
|
||||
|
||||
public void setIdsource(EntityWithSimpleId idsource) {
|
||||
this.idsource = idsource;
|
||||
}
|
||||
|
||||
public String getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(String data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
|
||||
@Entity(name = "ref_oto_derived")
|
||||
public static class EntityReferencingEntityWithOneToOneDerivedId implements Serializable {
|
||||
@Id
|
||||
private Integer id;
|
||||
|
||||
@ManyToOne
|
||||
private EntityWithOneToOneDerivedId ref;
|
||||
|
||||
public EntityReferencingEntityWithOneToOneDerivedId() {
|
||||
}
|
||||
|
||||
public EntityReferencingEntityWithOneToOneDerivedId(Integer id, EntityWithOneToOneDerivedId ref) {
|
||||
this.id = id;
|
||||
this.ref = ref;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public EntityWithOneToOneDerivedId getRef() {
|
||||
return ref;
|
||||
}
|
||||
|
||||
public void setRef(EntityWithOneToOneDerivedId ref) {
|
||||
this.ref = ref;
|
||||
}
|
||||
}
|
||||
|
||||
@Entity(name = "mto_derived")
|
||||
public static class EntityWithManyToOneDerivedId implements Serializable {
|
||||
@Id
|
||||
@ManyToOne
|
||||
private EntityWithSimpleId idsource;
|
||||
|
||||
private String data;
|
||||
|
||||
public EntityWithManyToOneDerivedId() {
|
||||
}
|
||||
|
||||
public EntityWithManyToOneDerivedId(EntityWithSimpleId idsource) {
|
||||
this.idsource = idsource;
|
||||
}
|
||||
|
||||
public EntityWithSimpleId getIdsource() {
|
||||
return idsource;
|
||||
}
|
||||
|
||||
public void setIdsource(EntityWithSimpleId idsource) {
|
||||
this.idsource = idsource;
|
||||
}
|
||||
|
||||
public String getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(String data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
|
||||
@Entity(name = "ref_mto_derived")
|
||||
public static class EntityReferencingEntityWithManyToOneDerivedId implements Serializable {
|
||||
@Id
|
||||
private Integer id;
|
||||
|
||||
@ManyToOne
|
||||
private EntityWithManyToOneDerivedId ref;
|
||||
|
||||
public EntityReferencingEntityWithManyToOneDerivedId() {
|
||||
}
|
||||
|
||||
public EntityReferencingEntityWithManyToOneDerivedId(Integer id, EntityWithManyToOneDerivedId ref) {
|
||||
this.id = id;
|
||||
this.ref = ref;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public EntityWithManyToOneDerivedId getRef() {
|
||||
return ref;
|
||||
}
|
||||
|
||||
public void setRef(EntityWithManyToOneDerivedId ref) {
|
||||
this.ref = ref;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -6,7 +6,9 @@
|
||||
*/
|
||||
package org.hibernate.test.util;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.boot.Metadata;
|
||||
import org.hibernate.mapping.Column;
|
||||
@ -18,6 +20,20 @@
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public abstract class SchemaUtil {
|
||||
public static Set<String> getColumnNames(String tableName, Metadata metadata) {
|
||||
Set<String> result = new HashSet<>();
|
||||
for ( Table table : metadata.collectTableMappings() ) {
|
||||
if (tableName.equals( table.getName() ) ) {
|
||||
Iterator<Column> columns = table.getColumnIterator();
|
||||
while ( columns.hasNext() ) {
|
||||
Column column = columns.next();
|
||||
result.add( column.getName() );
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static boolean isColumnPresent(String tableName, String columnName, Metadata metadata) {
|
||||
for ( Table table : metadata.collectTableMappings() ) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user