HHH-17158 detect incorrect use of @JoinColumn outside @JoinTable/@CollectionTable

This commit is contained in:
Gavin King 2023-09-04 11:03:40 +02:00
parent b73b4eb7e6
commit 70626c1e44
6 changed files with 30 additions and 24 deletions

View File

@ -413,21 +413,34 @@ public abstract class CollectionBinder {
PropertyHolder propertyHolder,
PropertyData inferredData,
XProperty property,
OneToMany oneToManyAnn,
ManyToMany manyToManyAnn,
ElementCollection elementCollectionAnn) {
if ( ( oneToManyAnn != null || manyToManyAnn != null || elementCollectionAnn != null )
&& isToManyAssociationWithinEmbeddableCollection(propertyHolder) ) {
String ann = oneToManyAnn != null ? "'@OneToMany'" : manyToManyAnn !=null ? "'@ManyToMany'" : "'@ElementCollection'";
throw new AnnotationException( "Property '" + getPath(propertyHolder, inferredData) +
"' belongs to an '@Embeddable' class that is contained in an '@ElementCollection' and may not be a " + ann );
OneToMany oneToMany,
ManyToMany manyToMany,
ElementCollection elementCollection) {
if ( ( oneToMany != null || manyToMany != null || elementCollection != null )
&& isToManyAssociationWithinEmbeddableCollection( propertyHolder ) ) {
throw new AnnotationException( "Property '" + getPath( propertyHolder, inferredData ) +
"' belongs to an '@Embeddable' class that is contained in an '@ElementCollection' and may not be a "
+ annotationName( oneToMany, manyToMany, elementCollection ));
}
if ( property.isAnnotationPresent( OrderColumn.class )
&& manyToManyAnn != null && !manyToManyAnn.mappedBy().isEmpty() ) {
throw new AnnotationException("Collection '" + getPath(propertyHolder, inferredData) +
&& manyToMany != null && !manyToMany.mappedBy().isEmpty() ) {
throw new AnnotationException("Collection '" + getPath( propertyHolder, inferredData ) +
"' is the unowned side of a bidirectional '@ManyToMany' and may not have an '@OrderColumn'");
}
if ( manyToMany != null || elementCollection != null ) {
if ( property.isAnnotationPresent( JoinColumn.class ) || property.isAnnotationPresent( JoinColumns.class ) ) {
throw new AnnotationException( "Property '" + getPath( propertyHolder, inferredData )
+ "' is a " + annotationName( oneToMany, manyToMany, elementCollection )
+ " and is directly annotated '@JoinColumn'"
+ " (specify '@JoinColumn' inside '@JoinTable' or '@CollectionTable')" );
}
}
}
private static String annotationName(OneToMany oneToMany, ManyToMany manyToMany, ElementCollection elementCollection) {
return oneToMany != null ? "'@OneToMany'" : manyToMany != null ? "'@ManyToMany'" : "'@ElementCollection'";
}
private static IndexColumn getIndexColumn(

View File

@ -10,7 +10,6 @@ import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.JoinTable;
import jakarta.persistence.OrderBy;
@ -57,7 +56,6 @@ public class Person {
@ElementCollection
@JoinColumn
@JoinTable(name = "T_NICKNAMES_A")
@OrderBy // testing default @OrderBy mapping
public Set<String> getNickNamesAscendingNaturalSort() {
@ -69,7 +67,6 @@ public class Person {
}
@ElementCollection
@JoinColumn
@JoinTable(name = "T_NICKNAMES_D")
@OrderBy( "desc" )
public Set<String> getNickNamesDescendingNaturalSort() {
@ -82,7 +79,6 @@ public class Person {
@ElementCollection
@JoinColumn
@OrderBy
@JoinTable(name = "T_ADDRESS_A")
public Set<Address> getAddressesAscendingNaturalSort() {
@ -94,7 +90,6 @@ public class Person {
}
@ElementCollection
@JoinColumn
@OrderBy( "desc" )
@JoinTable(name = "T_ADDRESS_D")
public Set<Address> getAddressesDescendingNaturalSort() {
@ -106,7 +101,6 @@ public class Person {
}
@ElementCollection
@JoinColumn
@OrderBy( "city" )
@JoinTable(name = "T_ADD_CITY_A")
public Set<Address> getAddressesCityAscendingSort() {
@ -118,7 +112,6 @@ public class Person {
}
@ElementCollection
@JoinColumn
@OrderBy( "city desc" )
@JoinTable(name = "T_ADD_CITY_D")
public Set<Address> getAddressesCityDescendingSort() {

View File

@ -14,12 +14,9 @@ import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.JoinTable;
import jakarta.persistence.ManyToMany;
import org.hibernate.orm.test.jpa.emops.Competitor;
/**
* @author Emmanuel Bernard
*/
@ -32,7 +29,6 @@ public class Competition {
@ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE },
fetch = FetchType.LAZY)
@JoinTable(name="competition_competitor")
@JoinColumn
private List<Competitor> competitors = new ArrayList<Competitor>();

View File

@ -8,6 +8,8 @@ package org.hibernate.orm.test.mapping.collections.custom.parameterized;
import java.util.ArrayList;
import java.util.List;
import jakarta.persistence.CollectionTable;
import jakarta.persistence.Column;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.FetchType;
@ -50,7 +52,7 @@ public class Entity {
type = DefaultableListType.class,
parameters = @Parameter(name = "default", value = "Hello" )
)
@JoinColumn( name = "ENT_ID" )
@CollectionTable(name = "ENTVALS", joinColumns = @JoinColumn( name = "ENT_ID" ))
@OrderColumn( name = "POS" )
@Column(name = "VAL")
public List getValues() {

View File

@ -15,6 +15,7 @@ import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.JoinTable;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.Table;
@ -116,7 +117,7 @@ public class BasicWhereTest extends BaseEnversJPAFunctionalTestCase {
private String name;
@ManyToMany
@JoinColumn(name = "allC")
@JoinTable(joinColumns = @JoinColumn(name = "allC"))
@SQLRestriction("type = 'C'")
@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
@AuditJoinTable(name = "A_C_AUD")

View File

@ -15,6 +15,7 @@ import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.JoinTable;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
@ -118,7 +119,7 @@ public class BasicWhereTest extends BaseEnversJPAFunctionalTestCase {
private String name;
@OneToMany
@JoinColumn(name = "allC")
@JoinTable(joinColumns = @JoinColumn(name = "allC"))
@SQLRestriction("type = 'C'")
@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
@AuditJoinTable(name = "A_C_AUD")