Skip to content

Commit aadd725

Browse files
author
Vincent Bouthinon
committed
HHH-18750 : @onetomany with @Any mapped in secondary table KO (ClassCastException)
He mistakenly assumes, at first glance, that the mappedBy attribut is not a @manytoone or @Any because the mappedBy attribut is mapped in a secondary table and therefore has a join. The problem appears later during a cast where the instance of type DiscriminatedAssociationAttributeMapping is cast to PluralAttributeMapping. https://hibernate.atlassian.net/browse/HHH-18750
1 parent 044d914 commit aadd725

File tree

1 file changed

+114
-0
lines changed

1 file changed

+114
-0
lines changed
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*
2+
* SPDX-License-Identifier: LGPL-2.1-or-later
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.orm.test.mapping.manytoone;
6+
7+
import jakarta.persistence.CascadeType;
8+
import jakarta.persistence.Column;
9+
import jakarta.persistence.Entity;
10+
import jakarta.persistence.GeneratedValue;
11+
import jakarta.persistence.Id;
12+
import jakarta.persistence.JoinColumn;
13+
import jakarta.persistence.OneToMany;
14+
import jakarta.persistence.SecondaryTable;
15+
import jakarta.persistence.Table;
16+
import org.hibernate.annotations.Any;
17+
import org.hibernate.annotations.AnyKeyJavaClass;
18+
import org.hibernate.annotations.Fetch;
19+
import org.hibernate.annotations.FetchMode;
20+
import org.hibernate.cfg.JdbcSettings;
21+
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
22+
import org.hibernate.testing.orm.junit.JiraKey;
23+
import org.hibernate.testing.orm.junit.Jpa;
24+
import org.hibernate.testing.orm.junit.Setting;
25+
import org.junit.jupiter.api.Assertions;
26+
import org.junit.jupiter.api.Test;
27+
28+
import java.util.HashSet;
29+
import java.util.List;
30+
import java.util.Set;
31+
32+
import static jakarta.persistence.FetchType.LAZY;
33+
34+
/**
35+
* Allows testing a @OneToMany mappedBy relationship with a @Any as the return variable and persist in secondary table.
36+
*
37+
* @author Vincent Bouthinon
38+
*/
39+
@Jpa(
40+
annotatedClasses = {
41+
ManyToOneWithAnyAndSameEntityTest.Actor.class,
42+
ManyToOneWithAnyAndSameEntityTest.Contact.class
43+
},
44+
integrationSettings = @Setting(name = JdbcSettings.SHOW_SQL, value = "true")
45+
)
46+
@JiraKey("HHH-18750")
47+
class ManyToOneWithAnyAndSameEntityTest {
48+
49+
@Test
50+
void testMappingManyToOneMappedByAnyPersistedInSecondaryTable(EntityManagerFactoryScope scope) {
51+
scope.inTransaction(
52+
entityManager -> {
53+
Actor actor = new Actor();
54+
actor.addToContacts( new Contact() );
55+
entityManager.persist( actor );
56+
entityManager.flush();
57+
entityManager.clear();
58+
59+
List<Actor> actors = entityManager.createQuery( "select a from actor a", Actor.class )
60+
.getResultList();
61+
Assertions.assertEquals( actors.size(), 2 );
62+
}
63+
);
64+
}
65+
66+
67+
@Entity(name = "actor")
68+
@Table(name = "TACTOR")
69+
public static class Actor {
70+
71+
@Id
72+
@GeneratedValue
73+
private Long id;
74+
75+
@OneToMany(mappedBy = "objetMaitre", cascade = {CascadeType.ALL})
76+
@Fetch(FetchMode.SELECT)
77+
private Set<Contact> contacts = new HashSet<>();
78+
79+
public Set<Contact> getContacts() {
80+
return contacts;
81+
}
82+
83+
public void setContacts(Set<Contact> contacts) {
84+
this.contacts = contacts;
85+
}
86+
87+
public void addToContacts(Contact contact) {
88+
this.contacts.add( contact );
89+
contact.setObjetMaitre( this );
90+
}
91+
}
92+
93+
@Entity(name = "contact")
94+
@SecondaryTable(name = "TPERSONNEPHYSIQUE")
95+
public static class Contact extends Actor {
96+
@Id
97+
@GeneratedValue
98+
private Long id;
99+
100+
@Any(fetch = LAZY)
101+
@AnyKeyJavaClass(Long.class)
102+
@JoinColumn(name = "OBJETMAITRE_ID", table = "TPERSONNEPHYSIQUE")
103+
@Column(name = "OBJETMAITRE_ROLE")
104+
private Actor objetMaitre;
105+
106+
public Actor getObjetMaitre() {
107+
return objetMaitre;
108+
}
109+
110+
public void setObjetMaitre(Actor objetMaitre) {
111+
this.objetMaitre = objetMaitre;
112+
}
113+
}
114+
}

0 commit comments

Comments
 (0)