HHH-16514 - Property sorting can lead to incorrect column mappings with derived embeddable keys
(cherry picked from commit 60b6fe3d9f
)
This commit is contained in:
parent
26ba40365f
commit
1ead5d2b37
|
@ -57,7 +57,6 @@ import static org.hibernate.internal.util.collections.CollectionHelper.isNotEmpt
|
|||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public class TableBinder {
|
||||
//TODO move it to a getter/setter strategy
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, TableBinder.class.getName() );
|
||||
|
||||
private MetadataBuildingContext buildingContext;
|
||||
|
@ -550,6 +549,12 @@ public class TableBinder {
|
|||
// if columns are implicit, then create the columns based
|
||||
// on the referenced entity id columns
|
||||
bindImplicitColumns( referencedEntity, joinColumns, value );
|
||||
if ( value instanceof ToOne ) {
|
||||
// in the case of implicit foreign-keys, make sure the columns making up
|
||||
// the foreign-key do not get resorted since the order is already properly
|
||||
// ascertained from the referenced identifier
|
||||
( (ToOne) value ).setSorted( true );
|
||||
}
|
||||
}
|
||||
else {
|
||||
bindExplicitColumns( referencedEntity, joinColumns, value, buildingContext, associatedClass );
|
||||
|
@ -586,7 +591,6 @@ public class TableBinder {
|
|||
PersistentClass associatedClass) {
|
||||
//implicit case, we hope PK and FK columns are in the same order
|
||||
if ( joinColumns.getColumns().size() != referencedEntity.getIdentifier().getColumnSpan() ) {
|
||||
// TODO: what about secondary tables?? associatedClass is null?
|
||||
throw new AnnotationException(
|
||||
"An association that targets entity '" + referencedEntity.getEntityName()
|
||||
+ "' from entity '" + associatedClass.getEntityName()
|
||||
|
@ -669,7 +673,7 @@ public class TableBinder {
|
|||
columns = referencedTable.getPrimaryKey().getColumns();
|
||||
break;
|
||||
}
|
||||
catch ( MappingException i ) {
|
||||
catch (MappingException ignore) {
|
||||
}
|
||||
}
|
||||
if ( referencedColumn == null ) {
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* 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.foreignkeys.sorting;
|
||||
|
||||
import jakarta.persistence.CascadeType;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@Entity
|
||||
public class A {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private int id;
|
||||
|
||||
@ManyToOne(cascade = CascadeType.PERSIST)
|
||||
B b;
|
||||
|
||||
public A() {
|
||||
}
|
||||
|
||||
public A(B b) {
|
||||
this.b = b;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* 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.foreignkeys.sorting;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.EnumType;
|
||||
import jakarta.persistence.Enumerated;
|
||||
import jakarta.persistence.Id;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@Entity
|
||||
public class B {
|
||||
enum Type {ONE,ANOTHER}
|
||||
|
||||
@Id
|
||||
@Column(length = 12)
|
||||
String code;
|
||||
|
||||
@Id
|
||||
@Column(precision = 10, scale = 0)
|
||||
BigDecimal cost;
|
||||
|
||||
@Id
|
||||
@Enumerated(EnumType.STRING)
|
||||
Type type;
|
||||
|
||||
@Id
|
||||
long id;
|
||||
|
||||
String name;
|
||||
|
||||
public B() {
|
||||
}
|
||||
|
||||
public B(String code, BigDecimal cost, Type type, long id, String name) {
|
||||
this.code = code;
|
||||
this.cost = cost;
|
||||
this.type = type;
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* 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.foreignkeys.sorting;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.Jira;
|
||||
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 = { A.class, B.class })
|
||||
@SessionFactory
|
||||
public class ForeignKeyColumnSortingTests {
|
||||
@Test
|
||||
@Jira( "https://hibernate.atlassian.net/browse/HHH-16514" )
|
||||
public void testDerivedCompositeFk(SessionFactoryScope sfScope) {
|
||||
|
||||
sfScope.inTransaction( (session) -> {
|
||||
final B b = new B( "abc", new BigDecimal( 1 ), B.Type.ONE, 1L, "tester" );
|
||||
session.persist( b );
|
||||
session.persist( new A( b ) );
|
||||
} );
|
||||
|
||||
sfScope.inTransaction( (session) -> {
|
||||
final A loaded = session.get( A.class, 1 );
|
||||
assertThat( loaded ).isNotNull();
|
||||
assertThat( loaded.b ).isNotNull();
|
||||
assertThat( loaded.b.name ).isEqualTo( "tester" );
|
||||
} );
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue