Skip to content

Commit 8687183

Browse files
committed
[#2330] Test collection events with StatelessSession
Add test from ORM issue HHH-19523
1 parent 568a5c8 commit 8687183

File tree

1 file changed

+245
-0
lines changed

1 file changed

+245
-0
lines changed
Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
/* Hibernate, Relational Persistence for Idiomatic Java
2+
*
3+
* SPDX-License-Identifier: Apache-2.0
4+
* Copyright: Red Hat Inc. and Hibernate Authors
5+
*/
6+
package org.hibernate.reactive;
7+
8+
import java.util.ArrayList;
9+
import java.util.Collection;
10+
import java.util.List;
11+
import java.util.Set;
12+
13+
import org.hibernate.engine.spi.SessionFactoryImplementor;
14+
import org.hibernate.event.service.spi.EventListenerRegistry;
15+
import org.hibernate.event.spi.AbstractCollectionEvent;
16+
import org.hibernate.event.spi.EventType;
17+
import org.hibernate.event.spi.PostCollectionRecreateEvent;
18+
import org.hibernate.event.spi.PostCollectionRecreateEventListener;
19+
import org.hibernate.event.spi.PostCollectionRemoveEvent;
20+
import org.hibernate.event.spi.PostCollectionRemoveEventListener;
21+
import org.hibernate.event.spi.PreCollectionRecreateEvent;
22+
import org.hibernate.event.spi.PreCollectionRecreateEventListener;
23+
import org.hibernate.event.spi.PreCollectionRemoveEvent;
24+
import org.hibernate.event.spi.PreCollectionRemoveEventListener;
25+
26+
import org.junit.jupiter.api.Test;
27+
28+
import io.vertx.junit5.VertxTestContext;
29+
import jakarta.persistence.Column;
30+
import jakarta.persistence.Entity;
31+
import jakarta.persistence.GeneratedValue;
32+
import jakarta.persistence.GenerationType;
33+
import jakarta.persistence.Id;
34+
import jakarta.persistence.JoinColumn;
35+
import jakarta.persistence.OneToMany;
36+
import jakarta.persistence.Table;
37+
38+
import static org.assertj.core.api.Assertions.assertThat;
39+
40+
/**
41+
* Adapt test in ORM: CollectionStatelessSessionListenerTest
42+
*/
43+
public class CollectionStatelessSessionListenerTest extends BaseReactiveTest {
44+
45+
@Override
46+
protected Collection<Class<?>> annotatedEntities() {
47+
return Set.of( EntityA.class, EntityB.class );
48+
}
49+
50+
@Test
51+
public void mutinyStatelessInsert(VertxTestContext context) {
52+
final List<AbstractCollectionEvent> events = new ArrayList<>();
53+
initializeListeners( events );
54+
55+
EntityA a = new EntityA();
56+
EntityB b = new EntityB();
57+
a.children.add( b );
58+
test( context, getMutinySessionFactory()
59+
.withStatelessTransaction( statelessSession -> statelessSession
60+
.insert( b )
61+
.chain( () -> statelessSession.insert( a ) )
62+
.chain( () -> statelessSession.delete( a ) )
63+
.chain( () -> statelessSession.delete( b ) )
64+
)
65+
.invoke( () -> assertEvents( events ) )
66+
);
67+
}
68+
69+
@Test
70+
public void mutinyStatelessInsertAll(VertxTestContext context) {
71+
final List<AbstractCollectionEvent> events = new ArrayList<>();
72+
initializeListeners( events );
73+
74+
EntityA a = new EntityA();
75+
EntityB b = new EntityB();
76+
a.children.add( b );
77+
test( context, getMutinySessionFactory()
78+
.withStatelessTransaction( statelessSession -> statelessSession
79+
.insertAll( b, a )
80+
.chain( () -> statelessSession.deleteAll( a, b ) )
81+
)
82+
.invoke( () -> assertEvents( events ) )
83+
);
84+
}
85+
86+
@Test
87+
public void stageStatelessInsert(VertxTestContext context) {
88+
final List<AbstractCollectionEvent> events = new ArrayList<>();
89+
initializeListeners( events );
90+
91+
EntityA a = new EntityA();
92+
EntityB b = new EntityB();
93+
a.children.add( b );
94+
test( context, getSessionFactory()
95+
.withStatelessTransaction( statelessSession -> statelessSession
96+
.insert( b )
97+
.thenCompose( v -> statelessSession.insert( a ) )
98+
.thenCompose( v -> statelessSession.delete( a ) )
99+
.thenCompose( v -> statelessSession.delete( b ) )
100+
)
101+
.thenAccept( v -> assertEvents( events ) )
102+
);
103+
}
104+
105+
@Test
106+
public void stageStatelessInsertAll(VertxTestContext context) {
107+
final List<AbstractCollectionEvent> events = new ArrayList<>();
108+
initializeListeners( events );
109+
110+
EntityA a = new EntityA();
111+
EntityB b = new EntityB();
112+
a.children.add( b );
113+
test( context, getSessionFactory()
114+
.withStatelessTransaction( statelessSession -> statelessSession
115+
.insert( b, a )
116+
.thenCompose( v -> statelessSession.delete( a, b ) )
117+
)
118+
.thenAccept( v -> assertEvents( events ) )
119+
);
120+
}
121+
122+
private static void assertEvents(List<AbstractCollectionEvent> events) {
123+
assertThat( events ).hasSize( 4 );
124+
assertThat( events.get( 0 ) )
125+
.isInstanceOf( PreCollectionRecreateEvent.class )
126+
.extracting( AbstractCollectionEvent::getAffectedOwnerEntityName ).isEqualTo( EntityA.class.getName() );
127+
assertThat( events.get( 1 ) )
128+
.isInstanceOf( PostCollectionRecreateEvent.class )
129+
.extracting( AbstractCollectionEvent::getAffectedOwnerEntityName ).isEqualTo( EntityA.class.getName() );
130+
assertThat( events.get( 2 ) )
131+
.isInstanceOf( PreCollectionRemoveEvent.class )
132+
.extracting( AbstractCollectionEvent::getAffectedOwnerEntityName ).isEqualTo( EntityA.class.getName() );
133+
assertThat( events.get( 3 ) )
134+
.isInstanceOf( PostCollectionRemoveEvent.class )
135+
.extracting( AbstractCollectionEvent::getAffectedOwnerEntityName ).isEqualTo( EntityA.class.getName() );
136+
}
137+
138+
private void initializeListeners(List<AbstractCollectionEvent> events) {
139+
final EventListenerRegistry registry = ( (SessionFactoryImplementor) factoryManager
140+
.getHibernateSessionFactory() )
141+
.getEventListenerRegistry();
142+
143+
// Clear previous listeners
144+
registry.getEventListenerGroup( EventType.PRE_COLLECTION_RECREATE )
145+
.clearListeners();
146+
registry.getEventListenerGroup( EventType.PRE_COLLECTION_REMOVE )
147+
.clearListeners();
148+
registry.getEventListenerGroup( EventType.POST_COLLECTION_RECREATE )
149+
.clearListeners();
150+
registry.getEventListenerGroup( EventType.POST_COLLECTION_REMOVE )
151+
.clearListeners();
152+
153+
// Add new listeners
154+
registry.getEventListenerGroup( EventType.PRE_COLLECTION_RECREATE )
155+
.appendListener( new MyPreCollectionRecreateEventListener( events ) );
156+
registry.getEventListenerGroup( EventType.PRE_COLLECTION_REMOVE )
157+
.appendListener( new MyPreCollectionRemoveEventListener( events ) );
158+
registry.getEventListenerGroup( EventType.POST_COLLECTION_RECREATE )
159+
.appendListener( new MyPostCollectionRecreateEventListener( events ) );
160+
registry.getEventListenerGroup( EventType.POST_COLLECTION_REMOVE )
161+
.appendListener( new MyPostCollectionRemoveEventListener( events ) );
162+
}
163+
164+
@Entity
165+
@Table(name = "ENTITY_A")
166+
public static class EntityA {
167+
168+
@Id
169+
@GeneratedValue(strategy = GenerationType.AUTO)
170+
@Column(name = "ID")
171+
Integer id;
172+
173+
@OneToMany
174+
@JoinColumn(name = "ENTITY_A")
175+
Collection<EntityB> children = new ArrayList<>();
176+
}
177+
178+
@Entity
179+
@Table(name = "ENTITY_B")
180+
public class EntityB {
181+
@Id
182+
@GeneratedValue(strategy = GenerationType.AUTO)
183+
@Column(name = "ID")
184+
Integer id;
185+
}
186+
187+
public static class MyPreCollectionRecreateEventListener implements PreCollectionRecreateEventListener {
188+
189+
private final List<AbstractCollectionEvent> events;
190+
191+
192+
public MyPreCollectionRecreateEventListener(List<AbstractCollectionEvent> events) {
193+
this.events = events;
194+
}
195+
196+
@Override
197+
public void onPreRecreateCollection(PreCollectionRecreateEvent event) {
198+
events.add( event );
199+
}
200+
201+
}
202+
203+
public static class MyPreCollectionRemoveEventListener implements PreCollectionRemoveEventListener {
204+
205+
private final List<AbstractCollectionEvent> events;
206+
207+
public MyPreCollectionRemoveEventListener(List<AbstractCollectionEvent> events) {
208+
this.events = events;
209+
}
210+
211+
@Override
212+
public void onPreRemoveCollection(PreCollectionRemoveEvent event) {
213+
events.add( event );
214+
}
215+
216+
}
217+
218+
public static class MyPostCollectionRecreateEventListener implements PostCollectionRecreateEventListener {
219+
220+
private final List<AbstractCollectionEvent> events;
221+
222+
public MyPostCollectionRecreateEventListener(List<AbstractCollectionEvent> events) {
223+
this.events = events;
224+
}
225+
226+
@Override
227+
public void onPostRecreateCollection(PostCollectionRecreateEvent event) {
228+
events.add( event );
229+
}
230+
}
231+
232+
public static class MyPostCollectionRemoveEventListener implements PostCollectionRemoveEventListener {
233+
234+
private final List<AbstractCollectionEvent> events;
235+
236+
public MyPostCollectionRemoveEventListener(List<AbstractCollectionEvent> events) {
237+
this.events = events;
238+
}
239+
240+
@Override
241+
public void onPostRemoveCollection(PostCollectionRemoveEvent event) {
242+
events.add( event );
243+
}
244+
}
245+
}

0 commit comments

Comments
 (0)