HHH-16592 error when @MapsId refers to id property with @Column mappings
This commit is contained in:
parent
7074188875
commit
c014abb0d5
|
@ -280,6 +280,7 @@ public class AnnotatedColumn {
|
|||
}
|
||||
else {
|
||||
mappingColumn = new Column();
|
||||
mappingColumn.setExplicit( !isImplicit );
|
||||
redefineColumnName( columnName, propertyName, applyNamingStrategy );
|
||||
mappingColumn.setLength( length );
|
||||
if ( precision != null && precision > 0 ) { //relevant precision
|
||||
|
|
|
@ -316,6 +316,7 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
|
|||
final String columnName = defaultColumnName( columnIndex, referencedEntity, logicalReferencedColumn );
|
||||
//yuk side effect on an implicit column
|
||||
setLogicalColumnName( columnName );
|
||||
setImplicit( true );
|
||||
setReferencedColumn( logicalReferencedColumn );
|
||||
final Column mappingColumn = getMappingColumn();
|
||||
initMappingColumn(
|
||||
|
@ -335,16 +336,23 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
|
|||
|
||||
private String defaultColumnName(int columnIndex, PersistentClass referencedEntity, String logicalReferencedColumn) {
|
||||
final AnnotatedJoinColumns parent = getParent();
|
||||
// if ( parent.hasMapsId() ) {
|
||||
// // infer the join column of the association
|
||||
// // from the name of the mapped primary key
|
||||
// // column (this is not required by the JPA
|
||||
// // spec) and is arguably backwards, given
|
||||
// // the name of the @MapsId annotation, but
|
||||
// // it's better than just having two different
|
||||
// // column names which disagree
|
||||
// return parent.resolveMapsId().getValue().getColumns().get( columnIndex ).getQuotedName();
|
||||
// }
|
||||
if ( parent.hasMapsId() ) {
|
||||
// infer the join column of the association
|
||||
// from the name of the mapped primary key
|
||||
// column (this is not required by the JPA
|
||||
// spec) and is arguably backwards, given
|
||||
// the name of the @MapsId annotation, but
|
||||
// it's better than just having two different
|
||||
// column names which disagree
|
||||
final Column column = parent.resolveMapsId().getValue().getColumns().get( columnIndex );
|
||||
// return column.getQuotedName();
|
||||
if ( column.isExplicit() ) {
|
||||
throw new AnnotationException( "Association '" + parent.getPropertyName()
|
||||
+ "' in entity '" + parent.getPropertyHolder().getEntityName()
|
||||
+ "' is annotated '@MapsId' but refers to a property '"
|
||||
+ parent.getMapsId() + "' which has an explicit column mapping" );
|
||||
}
|
||||
}
|
||||
// else {
|
||||
return parent.buildDefaultColumnName( referencedEntity, logicalReferencedColumn );
|
||||
// }
|
||||
|
|
|
@ -57,6 +57,7 @@ public class Column implements Selectable, Serializable, Cloneable, ColumnTypeIn
|
|||
private String sqlTypeName;
|
||||
private Integer sqlTypeCode;
|
||||
private boolean quoted;
|
||||
private boolean explicit;
|
||||
int uniqueInteger;
|
||||
private String comment;
|
||||
private String defaultValue;
|
||||
|
@ -117,6 +118,14 @@ public class Column implements Selectable, Serializable, Cloneable, ColumnTypeIn
|
|||
}
|
||||
}
|
||||
|
||||
public boolean isExplicit() {
|
||||
return explicit;
|
||||
}
|
||||
|
||||
public void setExplicit(boolean explicit) {
|
||||
this.explicit = explicit;
|
||||
}
|
||||
|
||||
private static boolean isQuoted(String name) {
|
||||
//TODO: deprecated, remove eventually
|
||||
return name != null
|
||||
|
|
|
@ -13,6 +13,7 @@ import org.hibernate.testing.orm.junit.SessionFactory;
|
|||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -107,7 +108,6 @@ public class DefaultedMapsIdTest {
|
|||
@IdClass(ExtensionId.class)
|
||||
static class Extension {
|
||||
@Id
|
||||
// @Column(name = "EX_LOAN_ID")
|
||||
private Long exLoanId;
|
||||
|
||||
@Id
|
||||
|
@ -119,7 +119,6 @@ public class DefaultedMapsIdTest {
|
|||
|
||||
@ManyToOne
|
||||
@MapsId("exLoanId")
|
||||
// @JoinColumn(name = "EX_LOAN_ID")
|
||||
private Loan loan;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import jakarta.persistence.Embeddable;
|
|||
import jakarta.persistence.EmbeddedId;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.MapsId;
|
||||
import jakarta.persistence.OneToMany;
|
||||
|
@ -82,10 +83,9 @@ public class MapsEmbeddedIdTest {
|
|||
@Embeddable
|
||||
public static class ExtensionId {
|
||||
|
||||
// @Column(name="EX_LOAN_ID")
|
||||
private Long exLoanId;
|
||||
|
||||
// @Column(name="EX_NO")
|
||||
@Column(name="EX_NO")
|
||||
private int exNo;
|
||||
|
||||
public ExtensionId(Long exLoanId, int exNo) {
|
||||
|
@ -114,8 +114,6 @@ public class MapsEmbeddedIdTest {
|
|||
static class Extension {
|
||||
|
||||
@EmbeddedId
|
||||
@AttributeOverride(name = "exLoanId", column = @Column(name="EX_LOAN_ID"))
|
||||
@AttributeOverride(name = "exNo", column = @Column(name="EX_NO"))
|
||||
private ExtensionId id;
|
||||
|
||||
@Column(name = "EX_EXTENSION_DAYS")
|
||||
|
@ -123,7 +121,7 @@ public class MapsEmbeddedIdTest {
|
|||
|
||||
@ManyToOne
|
||||
@MapsId("exLoanId")
|
||||
// @JoinColumn(name = "EX_LOAN_ID")
|
||||
@JoinColumn(name = "EX_LOAN_ID")
|
||||
private Loan loan;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
package org.hibernate.orm.test.annotations.mapsid;
|
||||
|
||||
import jakarta.persistence.AttributeOverride;
|
||||
import jakarta.persistence.CascadeType;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Embeddable;
|
||||
import jakarta.persistence.EmbeddedId;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.IdClass;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.MapsId;
|
||||
|
@ -23,27 +25,27 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
|||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
@SessionFactory
|
||||
@DomainModel(annotatedClasses = {MapsIdSpecTest.Loan.class, MapsIdSpecTest.Extension.class})
|
||||
public class MapsIdSpecTest {
|
||||
@DomainModel(annotatedClasses = {MapsEmbeddedIdWithOverrideTest.Loan.class, MapsEmbeddedIdWithOverrideTest.ExtensionId.class, MapsEmbeddedIdWithOverrideTest.Extension.class})
|
||||
public class MapsEmbeddedIdWithOverrideTest {
|
||||
|
||||
@Test void test(SessionFactoryScope scope) {
|
||||
ExtensionId eid = scope.fromTransaction( s -> {
|
||||
Loan loan = new Loan();
|
||||
loan.id = 999L;
|
||||
ExtensionId exid = new ExtensionId(loan.id, 1);
|
||||
Extension extension = new Extension();
|
||||
extension.exLoanId = loan.id;
|
||||
extension.id = exid;
|
||||
extension.loan = loan;
|
||||
extension.exNo = 1;
|
||||
extension.exExtensionDays = 30;
|
||||
loan.extensions.add(extension);
|
||||
exid = new ExtensionId(loan.id, 2);
|
||||
extension = new Extension();
|
||||
extension.exLoanId = loan.id;
|
||||
extension.id = exid;
|
||||
extension.loan = loan;
|
||||
extension.exNo = 2;
|
||||
extension.exExtensionDays = 14;
|
||||
loan.extensions.add(extension);
|
||||
s.persist(loan);
|
||||
return new ExtensionId(extension.exLoanId, extension.exNo );
|
||||
return exid;
|
||||
});
|
||||
scope.inSession( s -> {
|
||||
List<Extension> extensions = s.createQuery("from Extension", Extension.class).getResultList();
|
||||
|
@ -52,16 +54,16 @@ public class MapsIdSpecTest {
|
|||
scope.inSession( s -> {
|
||||
Extension extension = s.find(Extension.class, eid);
|
||||
assertEquals(14, extension.exExtensionDays);
|
||||
assertEquals(2, extension.exNo);
|
||||
assertEquals(999L, extension.exLoanId);
|
||||
assertEquals(2, extension.id.exNo);
|
||||
assertEquals(999L, extension.id.exLoanId);
|
||||
assertNotNull( extension.loan );
|
||||
});
|
||||
scope.inSession( s -> {
|
||||
Loan loan = s.find(Loan.class, eid.exLoanId);
|
||||
Extension extension = loan.extensions.get(0);
|
||||
assertEquals(1, extension.exNo);
|
||||
assertEquals(1, extension.id.exNo);
|
||||
assertEquals(30, extension.exExtensionDays);
|
||||
assertEquals(999L, extension.exLoanId);
|
||||
assertEquals(999L, extension.id.exLoanId);
|
||||
assertEquals(loan, extension.loan);
|
||||
});
|
||||
}
|
||||
|
@ -78,8 +80,11 @@ public class MapsIdSpecTest {
|
|||
private List<Extension> extensions = new ArrayList<>();
|
||||
}
|
||||
|
||||
static class ExtensionId {
|
||||
@Embeddable
|
||||
public static class ExtensionId {
|
||||
|
||||
private Long exLoanId;
|
||||
|
||||
private int exNo;
|
||||
|
||||
public ExtensionId(Long exLoanId, int exNo) {
|
||||
|
@ -105,15 +110,11 @@ public class MapsIdSpecTest {
|
|||
}
|
||||
|
||||
@Entity(name = "Extension")
|
||||
@IdClass(ExtensionId.class)
|
||||
static class Extension {
|
||||
@Id
|
||||
// @Column(name = "EX_LOAN_ID")
|
||||
private Long exLoanId;
|
||||
|
||||
@Id
|
||||
@Column(name = "EX_NO")
|
||||
private int exNo;
|
||||
@EmbeddedId
|
||||
@AttributeOverride(name = "exNo", column = @Column(name="EX_NO"))
|
||||
private ExtensionId id;
|
||||
|
||||
@Column(name = "EX_EXTENSION_DAYS")
|
||||
private int exExtensionDays;
|
|
@ -5,6 +5,7 @@ import jakarta.persistence.Column;
|
|||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.IdClass;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.MapsId;
|
||||
import jakarta.persistence.OneToMany;
|
||||
|
@ -13,7 +14,6 @@ import org.hibernate.testing.orm.junit.SessionFactory;
|
|||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -108,7 +108,6 @@ public class MapsIdTest {
|
|||
@IdClass(ExtensionId.class)
|
||||
static class Extension {
|
||||
@Id
|
||||
@Column(name = "EX_LOAN_ID") //TODO: this should really cause an error
|
||||
private Long exLoanId;
|
||||
|
||||
@Id
|
||||
|
@ -120,7 +119,7 @@ public class MapsIdTest {
|
|||
|
||||
@ManyToOne
|
||||
@MapsId("exLoanId")
|
||||
// @JoinColumn(name = "EX_LOAN_ID")
|
||||
@JoinColumn(name = "EX_LOAN_ID")
|
||||
private Loan loan;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
package org.hibernate.orm.test.annotations.mapsid;
|
||||
|
||||
import jakarta.persistence.CascadeType;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.MapsId;
|
||||
import jakarta.persistence.OneToMany;
|
||||
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.Test;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
@SessionFactory
|
||||
@DomainModel(annotatedClasses = {NoIdClassMapsIdTest.Loan.class, NoIdClassMapsIdTest.Extension.class})
|
||||
public class NoIdClassMapsIdTest {
|
||||
|
||||
@Test void test(SessionFactoryScope scope) {
|
||||
Extension eid = scope.fromTransaction( s -> {
|
||||
Loan loan = new Loan();
|
||||
loan.id = 999L;
|
||||
Extension extension = new Extension();
|
||||
extension.exLoanId = loan.id;
|
||||
extension.loan = loan;
|
||||
extension.exNo = 1;
|
||||
extension.exExtensionDays = 30;
|
||||
loan.extensions.add(extension);
|
||||
extension = new Extension();
|
||||
extension.exLoanId = loan.id;
|
||||
extension.loan = loan;
|
||||
extension.exNo = 2;
|
||||
extension.exExtensionDays = 14;
|
||||
loan.extensions.add(extension);
|
||||
s.persist(loan);
|
||||
return extension;
|
||||
});
|
||||
scope.inSession( s -> {
|
||||
List<Extension> extensions = s.createQuery("from Extension", Extension.class).getResultList();
|
||||
assertEquals(2, extensions.size());
|
||||
} );
|
||||
scope.inSession( s -> {
|
||||
Extension extension = s.find(Extension.class, eid);
|
||||
assertEquals(14, extension.exExtensionDays);
|
||||
assertEquals(2, extension.exNo);
|
||||
assertEquals(999L, extension.exLoanId);
|
||||
assertNotNull( extension.loan );
|
||||
});
|
||||
scope.inSession( s -> {
|
||||
Loan loan = s.find(Loan.class, eid.exLoanId);
|
||||
Extension extension = loan.extensions.get(0);
|
||||
assertEquals(1, extension.exNo);
|
||||
assertEquals(30, extension.exExtensionDays);
|
||||
assertEquals(999L, extension.exLoanId);
|
||||
assertEquals(loan, extension.loan);
|
||||
});
|
||||
}
|
||||
|
||||
@Entity(name = "Loan")
|
||||
static class Loan {
|
||||
@Id
|
||||
@Column(name = "LOAN_ID")
|
||||
private Long id;
|
||||
|
||||
private BigDecimal amount = BigDecimal.ZERO;
|
||||
|
||||
@OneToMany(cascade = CascadeType.ALL, mappedBy = "loan")
|
||||
private List<Extension> extensions = new ArrayList<>();
|
||||
}
|
||||
|
||||
|
||||
@Entity(name = "Extension")
|
||||
static class Extension {
|
||||
@Id
|
||||
private Long exLoanId;
|
||||
|
||||
@Id
|
||||
@Column(name = "EX_NO")
|
||||
private int exNo;
|
||||
|
||||
@Column(name = "EX_EXTENSION_DAYS")
|
||||
private int exExtensionDays;
|
||||
|
||||
@ManyToOne
|
||||
@MapsId("exLoanId")
|
||||
@JoinColumn(name = "EX_LOAN_ID")
|
||||
private Loan loan;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue