HHH-17871 Error if defining a ManyToAny in the child classes which references a @MappedSuperclass

This commit is contained in:
Vincent Bouthinon 2024-03-21 09:56:49 +01:00 committed by Christian Beikov
parent c32f0a08fa
commit 82f45fc741
2 changed files with 136 additions and 2 deletions

View File

@ -236,12 +236,16 @@ public class Any extends SimpleValue {
public boolean isSame(Any other) {
return super.isSame( other )
&& Objects.equals( keyMapping.getTypeName(), other.keyMapping.getTypeName() )
&& Objects.equals( metaMapping.getTypeName(), other.keyMapping.getTypeName() )
&& Objects.equals( getTypeNameOrNull( keyMapping ), getTypeNameOrNull( other.keyMapping ) )
&& Objects.equals( getTypeNameOrNull( metaMapping ), getTypeNameOrNull( other.metaMapping ) )
&& Objects.equals( metaValueToEntityNameMap, other.metaValueToEntityNameMap )
&& lazy == other.lazy;
}
private String getTypeNameOrNull(SimpleValue simpleValue) {
return simpleValue != null ? simpleValue.getTypeName() : null;
}
public boolean isValid(Mapping mapping) throws MappingException {
if ( discriminatorDescriptor != null ) {
return discriminatorDescriptor.isValid( mapping ) && keyDescriptor.isValid( mapping );

View File

@ -0,0 +1,130 @@
package org.hibernate.orm.test.associations.any;
import static jakarta.persistence.InheritanceType.SINGLE_TABLE;
import static org.hibernate.annotations.CascadeType.ALL;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.HashSet;
import java.util.Set;
import jakarta.persistence.Access;
import jakarta.persistence.AccessType;
import jakarta.persistence.Column;
import jakarta.persistence.DiscriminatorColumn;
import jakarta.persistence.DiscriminatorValue;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.Inheritance;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.JoinTable;
import jakarta.persistence.MappedSuperclass;
import jakarta.persistence.Table;
import jakarta.persistence.Transient;
import org.hibernate.Hibernate;
import org.hibernate.annotations.AnyKeyJavaClass;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.ManyToAny;
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
import org.hibernate.testing.orm.junit.JiraKey;
import org.hibernate.testing.orm.junit.Jpa;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@Jpa(
annotatedClasses = {
ManyToAnySubClassAccessPropertyTest.Person.class,
ManyToAnySubClassAccessPropertyTest.Animal.class,
ManyToAnySubClassAccessPropertyTest.Cat.class,
ManyToAnySubClassAccessPropertyTest.Dog.class,
ManyToAnySubClassAccessPropertyTest.DogHandler.class,
ManyToAnySubClassAccessPropertyTest.Military.class,
}
)
@JiraKey("HHH-17871")
class ManyToAnySubClassAccessPropertyTest {
@Test
void testManyToAnyThatReferencedAMappedSuperclassDefinedInMultipleSubClass(EntityManagerFactoryScope scope) {
scope.inTransaction(
entityManager -> {
Dog dog = new Dog();
dog.getOwners().add( new DogHandler() );
entityManager.persist( dog );
assertTrue( Hibernate.isInitialized( dog ) );
}
);
}
@Entity
@Inheritance(strategy = SINGLE_TABLE)
@DiscriminatorColumn(name = "ROLE", length = 100)
@Table(name = "TANIMAL")
public static class Animal {
@Id
@GeneratedValue
public Integer id;
@Transient
private Set<Person> owners = new HashSet<>();
public Set<Person> getOwners() {
return owners;
}
public void setOwners(Set<Person> owners) {
this.owners = owners;
}
}
@Entity
@DiscriminatorValue("DOG")
public static class Dog extends Animal {
@Access(AccessType.PROPERTY)
@ManyToAny
@AnyKeyJavaClass(Integer.class)
@Cascade(ALL)
@Column(name = "ROLE")
@JoinTable(name = "DOG_OWNER", joinColumns = @JoinColumn(name = "SOURCE"), inverseJoinColumns = @JoinColumn(name = "DEST"))
@Override
public Set<Person> getOwners() {
return super.getOwners();
}
}
@Entity
@DiscriminatorValue("CAT")
public static class Cat extends Animal {
@Access(AccessType.PROPERTY)
@ManyToAny
@AnyKeyJavaClass(Integer.class)
@Cascade(ALL)
@Column(name = "ROLE")
@JoinTable(name = "DOG_OWNER", joinColumns = @JoinColumn(name = "SOURCE"), inverseJoinColumns = @JoinColumn(name = "DEST"))
@Override
public Set<Person> getOwners() {
return super.getOwners();
}
}
@MappedSuperclass
public static class Person {
@Id
@GeneratedValue
private Integer id;
}
@Entity
public static class DogHandler extends Person {
}
@Entity
public static class Military extends Person {
}
}