Skip to content

Commit 9ca0019

Browse files
committed
HHH-18936 test for cascade REMOVE with @onDelete(CASCADE)
1 parent a7d29a0 commit 9ca0019

File tree

3 files changed

+117
-2
lines changed

3 files changed

+117
-2
lines changed
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.orm.test.ondeletecascade;
6+
7+
import jakarta.persistence.CascadeType;
8+
import jakarta.persistence.Entity;
9+
import jakarta.persistence.Id;
10+
import jakarta.persistence.ManyToOne;
11+
import jakarta.persistence.OneToMany;
12+
import org.hibernate.Hibernate;
13+
import org.hibernate.SessionFactory;
14+
import org.hibernate.annotations.OnDelete;
15+
import org.hibernate.annotations.OnDeleteAction;
16+
import org.hibernate.annotations.SQLDelete;
17+
import org.hibernate.engine.spi.SessionImplementor;
18+
import org.hibernate.stat.Statistics;
19+
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
20+
import org.hibernate.testing.orm.junit.Jpa;
21+
import org.junit.jupiter.api.Test;
22+
23+
import java.util.HashSet;
24+
import java.util.Set;
25+
26+
import static org.junit.jupiter.api.Assertions.assertEquals;
27+
import static org.junit.jupiter.api.Assertions.assertFalse;
28+
import static org.junit.jupiter.api.Assertions.assertTrue;
29+
30+
@Jpa(annotatedClasses =
31+
{OnDeleteCascadeRemoveTest.Parent.class,
32+
OnDeleteCascadeRemoveTest.Child.class},
33+
generateStatistics = true,
34+
useCollectingStatementInspector = true)
35+
class OnDeleteCascadeRemoveTest {
36+
@Test
37+
void testOnDeleteCascadeRemove1(EntityManagerFactoryScope scope) {
38+
Statistics statistics =
39+
scope.getEntityManagerFactory().unwrap( SessionFactory.class )
40+
.getStatistics();
41+
statistics.clear();
42+
scope.getCollectingStatementInspector().clear();
43+
scope.inTransaction( em -> {
44+
Parent parent = new Parent();
45+
Child child = new Child();
46+
parent.children.add( child );
47+
child.parent = parent;
48+
em.persist( parent );
49+
} );
50+
scope.inTransaction( em -> {
51+
Parent parent = em.find( Parent.class, 0L );
52+
assertFalse( Hibernate.isInitialized( parent.children ) );
53+
em.remove( parent );
54+
// note: ideally we would skip the initialization here
55+
assertTrue( Hibernate.isInitialized( parent.children ) );
56+
});
57+
assertEquals( 1L,statistics.getEntityStatistics(Child.class.getName()).getDeleteCount() );
58+
assertEquals( 5, scope.getCollectingStatementInspector().getSqlQueries().size() );
59+
long children =
60+
scope.fromTransaction( em -> em.createQuery( "select count(*) from CascadeChild", Long.class )
61+
.getSingleResult() );
62+
assertEquals( 0L, children );
63+
}
64+
65+
@Test
66+
void testOnDeleteCascadeRemove2(EntityManagerFactoryScope scope) {
67+
Statistics statistics =
68+
scope.getEntityManagerFactory().unwrap( SessionFactory.class )
69+
.getStatistics();
70+
statistics.clear();
71+
scope.getCollectingStatementInspector().clear();
72+
scope.inTransaction( em -> {
73+
Parent parent = new Parent();
74+
Child child = new Child();
75+
parent.children.add( child );
76+
child.parent = parent;
77+
em.persist( parent );
78+
} );
79+
scope.inTransaction( em -> {
80+
Parent parent = em.find( Parent.class, 0L );
81+
assertEquals(1, parent.children.size());
82+
assertTrue( Hibernate.isInitialized( parent.children ) );
83+
em.remove( parent );
84+
assertTrue( em.unwrap( SessionImplementor.class )
85+
.getPersistenceContext()
86+
.getEntry( parent.children.iterator().next() )
87+
.getStatus().isDeletedOrGone() );
88+
});
89+
assertEquals( 1L, statistics.getEntityStatistics(Child.class.getName()).getDeleteCount() );
90+
assertEquals( 5, scope.getCollectingStatementInspector().getSqlQueries().size() );
91+
long children =
92+
scope.fromTransaction( em -> em.createQuery( "select count(*) from CascadeChild", Long.class )
93+
.getSingleResult() );
94+
assertEquals( 0L, children );
95+
}
96+
97+
@Entity(name="CascadeParent")
98+
static class Parent {
99+
@Id
100+
long id;
101+
@OneToMany(mappedBy = "parent",
102+
cascade = {CascadeType.PERSIST, CascadeType.REMOVE})
103+
@OnDelete(action = OnDeleteAction.CASCADE)
104+
Set<Child> children = new HashSet<>();
105+
}
106+
@Entity(name="CascadeChild")
107+
@SQLDelete( sql = "should never happen" )
108+
static class Child {
109+
@Id
110+
long id;
111+
@OnDelete(action = OnDeleteAction.CASCADE)
112+
@ManyToOne
113+
Parent parent;
114+
}
115+
}

hibernate-core/src/test/java/org/hibernate/orm/test/OnDeleteTest.java renamed to hibernate-core/src/test/java/org/hibernate/orm/test/ondeletecascade/OnDeleteTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* SPDX-License-Identifier: Apache-2.0
33
* Copyright Red Hat Inc. and Hibernate Authors
44
*/
5-
package org.hibernate.orm.test;
5+
package org.hibernate.orm.test.ondeletecascade;
66

77
import jakarta.persistence.Entity;
88
import jakarta.persistence.Id;

hibernate-core/src/test/java/org/hibernate/orm/test/OnDeleteTest2.java renamed to hibernate-core/src/test/java/org/hibernate/orm/test/ondeletecascade/OnDeleteTest2.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* SPDX-License-Identifier: Apache-2.0
33
* Copyright Red Hat Inc. and Hibernate Authors
44
*/
5-
package org.hibernate.orm.test;
5+
package org.hibernate.orm.test.ondeletecascade;
66

77
import jakarta.persistence.Entity;
88
import jakarta.persistence.Id;

0 commit comments

Comments
 (0)