Skip to content

Commit fa6042c

Browse files
committed
[#2207] fix cast to ReactiveSession that broke StatelessSession
1 parent 156f7c3 commit fa6042c

File tree

2 files changed

+281
-2
lines changed

2 files changed

+281
-2
lines changed

hibernate-reactive-core/src/main/java/org/hibernate/reactive/sql/results/graph/entity/internal/ReactiveEntitySelectFetchInitializer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
import org.hibernate.proxy.LazyInitializer;
2424
import org.hibernate.reactive.logging.impl.Log;
2525
import org.hibernate.reactive.logging.impl.LoggerFactory;
26-
import org.hibernate.reactive.session.ReactiveSession;
26+
import org.hibernate.reactive.session.ReactiveQueryProducer;
2727
import org.hibernate.reactive.sql.results.graph.ReactiveInitializer;
2828
import org.hibernate.spi.NavigablePath;
2929
import org.hibernate.sql.results.graph.AssemblerCreationState;
@@ -154,7 +154,7 @@ else if ( data.getInstance() == null ) {
154154
data.setState( State.INITIALIZED );
155155
final String entityName = concreteDescriptor.getEntityName();
156156

157-
return ( (ReactiveSession) session ).reactiveInternalLoad(
157+
return ( (ReactiveQueryProducer) session ).reactiveInternalLoad(
158158
entityName,
159159
data.getEntityIdentifier(),
160160
true,
Lines changed: 279 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,279 @@
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 io.vertx.junit5.Timeout;
9+
import io.vertx.junit5.VertxTestContext;
10+
import jakarta.persistence.*;
11+
import jakarta.persistence.criteria.*;
12+
import org.junit.jupiter.api.Test;
13+
14+
import java.util.Collection;
15+
import java.util.List;
16+
import java.util.Objects;
17+
18+
import static java.util.concurrent.TimeUnit.MINUTES;
19+
import static org.junit.jupiter.api.Assertions.*;
20+
21+
@Timeout(value = 10, timeUnit = MINUTES)
22+
23+
public class MutinyStatelessSessionTest extends BaseReactiveTest {
24+
25+
@Override
26+
protected Collection<Class<?>> annotatedEntities() {
27+
return List.of( GuineaPig.class );
28+
}
29+
30+
@Test
31+
public void testStatelessSession(VertxTestContext context) {
32+
GuineaPig pig = new GuineaPig( "Aloi" );
33+
test( context, getMutinySessionFactory().withStatelessSession( ss -> ss
34+
.insert( pig )
35+
.chain( v -> ss.createSelectionQuery( "from GuineaPig where name=:n", GuineaPig.class )
36+
.setParameter( "n", pig.name )
37+
.getResultList() )
38+
.invoke( list -> {
39+
assertFalse( list.isEmpty() );
40+
assertEquals( 1, list.size() );
41+
assertThatPigsAreEqual( pig, list.get( 0 ) );
42+
} )
43+
.chain( v -> ss.get( GuineaPig.class, pig.id ) )
44+
.chain( p -> {
45+
assertThatPigsAreEqual( pig, p );
46+
p.name = "X";
47+
return ss.update( p );
48+
} )
49+
.chain( v -> ss.refresh( pig ) )
50+
.invoke( v -> assertEquals( pig.name, "X" ) )
51+
.chain( v -> ss.createMutationQuery( "update GuineaPig set name='Y'" ).executeUpdate() )
52+
.chain( v -> ss.refresh( pig ) )
53+
.invoke( v -> assertEquals( pig.name, "Y" ) )
54+
.chain( v -> ss.delete( pig ) )
55+
.chain( v -> ss.createSelectionQuery( "from GuineaPig", GuineaPig.class ).getResultList() )
56+
.invoke( list -> assertTrue( list.isEmpty() ) ) )
57+
);
58+
}
59+
60+
@Test
61+
public void testStatelessSessionWithNamed(VertxTestContext context) {
62+
GuineaPig pig = new GuineaPig( "Aloi" );
63+
test( context, getMutinySessionFactory().withStatelessSession( ss -> ss
64+
.insert( pig )
65+
.chain( v -> ss.createNamedQuery( "findbyname", GuineaPig.class )
66+
.setParameter( "n", pig.name )
67+
.getResultList() )
68+
.invoke( list -> {
69+
assertFalse( list.isEmpty() );
70+
assertEquals( 1, list.size() );
71+
assertThatPigsAreEqual( pig, list.get( 0 ) );
72+
} )
73+
.chain( v -> ss.get( GuineaPig.class, pig.id ) )
74+
.chain( p -> {
75+
assertThatPigsAreEqual( pig, p );
76+
p.name = "X";
77+
return ss.update( p );
78+
} )
79+
.chain( v -> ss.refresh( pig ) )
80+
.invoke( v -> assertEquals( pig.name, "X" ) )
81+
.chain( v -> ss.createNamedQuery( "updatebyname" ).executeUpdate() )
82+
.chain( v -> ss.refresh( pig ) )
83+
.invoke( v -> assertEquals( pig.name, "Y" ) )
84+
.chain( v -> ss.delete( pig ) )
85+
.chain( v -> ss.createNamedQuery( "findall" ).getResultList() )
86+
.invoke( list -> assertTrue( list.isEmpty() ) ) )
87+
);
88+
}
89+
90+
@Test
91+
public void testStatelessSessionWithNative(VertxTestContext context) {
92+
GuineaPig pig = new GuineaPig( "Aloi" );
93+
test( context, getMutinySessionFactory().openStatelessSession()
94+
.chain( ss -> ss.insert( pig )
95+
.chain( v -> ss
96+
.createNativeQuery( "select * from Piggy where name=:n", GuineaPig.class )
97+
.setParameter( "n", pig.name )
98+
.getResultList() )
99+
.invoke( list -> {
100+
assertFalse( list.isEmpty() );
101+
assertEquals( 1, list.size() );
102+
assertThatPigsAreEqual( pig, list.get( 0 ) );
103+
} )
104+
.chain( v -> ss.get( GuineaPig.class, pig.id ) )
105+
.chain( p -> {
106+
assertThatPigsAreEqual( pig, p );
107+
p.name = "X";
108+
return ss.update( p );
109+
} )
110+
.chain( v -> ss.refresh( pig ) )
111+
.invoke( v -> assertEquals( pig.name, "X" ) )
112+
.chain( v -> ss.createNativeQuery( "update Piggy set name='Y'" )
113+
.executeUpdate() )
114+
.invoke( rows -> assertEquals( 1, rows ) )
115+
.chain( v -> ss.refresh( pig ) )
116+
.invoke( v -> assertEquals( pig.name, "Y" ) )
117+
.chain( v -> ss.delete( pig ) )
118+
.chain( v -> ss.createNativeQuery( "select id from Piggy" ).getResultList() )
119+
.invoke( list -> assertTrue( list.isEmpty() ) )
120+
.chain( v -> ss.close() ) )
121+
);
122+
}
123+
124+
@Test
125+
public void testStatelessSessionGetMultiple(VertxTestContext context) {
126+
GuineaPig a = new GuineaPig("A");
127+
GuineaPig b = new GuineaPig("B");
128+
GuineaPig c = new GuineaPig("C");
129+
test( context, getMutinySessionFactory().openStatelessSession()
130+
.chain( ss -> ss.insertMultiple( List.of(a, b, c) )
131+
.chain( v -> ss.get( GuineaPig.class, a.id, c.id ) )
132+
.invoke( list -> {
133+
assertEquals( 2, list.size() );
134+
assertThatPigsAreEqual( a, list.get( 0 ) );
135+
assertThatPigsAreEqual( c, list.get( 1 ) );
136+
})
137+
.chain( v -> ss.close() ) )
138+
);
139+
}
140+
141+
@Test
142+
public void testStatelessSessionCriteria(VertxTestContext context) {
143+
GuineaPig pig = new GuineaPig( "Aloi" );
144+
GuineaPig mate = new GuineaPig("Aloina");
145+
pig.mate = mate;
146+
147+
CriteriaBuilder cb = getSessionFactory().getCriteriaBuilder();
148+
149+
CriteriaQuery<GuineaPig> query = cb.createQuery( GuineaPig.class );
150+
Root<GuineaPig> gp = query.from( GuineaPig.class );
151+
query.where( cb.equal( gp.get( "name" ), cb.parameter( String.class, "n" ) ) );
152+
query.orderBy( cb.asc( gp.get( "name" ) ) );
153+
154+
CriteriaUpdate<GuineaPig> update = cb.createCriteriaUpdate( GuineaPig.class );
155+
Root<GuineaPig> updatedPig = update.from(GuineaPig.class);
156+
update.set( "name", "Bob" );
157+
update.where( updatedPig.get( "mate" ).isNotNull() );
158+
159+
CriteriaDelete<GuineaPig> delete = cb.createCriteriaDelete( GuineaPig.class );
160+
Root<GuineaPig> deletedPig = delete.from( GuineaPig.class );
161+
delete.where( deletedPig.get( "mate" ).isNotNull() );
162+
163+
test( context, getMutinySessionFactory().openStatelessSession()
164+
.chain( ss -> ss.insertMultiple( List.of(mate, pig) )
165+
.chain( v -> ss.createQuery( query )
166+
.setParameter( "n", pig.name )
167+
.getResultList() )
168+
.invoke( list -> {
169+
assertFalse( list.isEmpty() );
170+
assertEquals( 1, list.size() );
171+
assertThatPigsAreEqual( pig, list.get( 0 ) );
172+
} )
173+
.chain( v -> ss.createQuery( update ).executeUpdate() )
174+
.invoke( rows -> assertEquals( 1, rows ) )
175+
.chain( v -> ss.createQuery( delete ).executeUpdate() )
176+
.invoke( rows -> assertEquals( 1, rows ) )
177+
.chain( v -> ss.close() ) )
178+
);
179+
}
180+
181+
@Test
182+
public void testTransactionPropagation(VertxTestContext context) {
183+
test( context, getMutinySessionFactory().withStatelessSession(
184+
session -> session.withTransaction( transaction -> session.createSelectionQuery( "from GuineaPig", GuineaPig.class )
185+
.getResultList()
186+
.chain( list -> {
187+
assertNotNull( session.currentTransaction() );
188+
assertFalse( session.currentTransaction().isMarkedForRollback() );
189+
session.currentTransaction().markForRollback();
190+
assertTrue( session.currentTransaction().isMarkedForRollback() );
191+
assertTrue( transaction.isMarkedForRollback() );
192+
return session.withTransaction( t -> {
193+
assertTrue( t.isMarkedForRollback() );
194+
return session.createSelectionQuery( "from GuineaPig", GuineaPig.class ).getResultList();
195+
} );
196+
} ) )
197+
) );
198+
}
199+
200+
@Test
201+
public void testSessionPropagation(VertxTestContext context) {
202+
test( context, getMutinySessionFactory().withStatelessSession(
203+
session -> session.createSelectionQuery( "from GuineaPig", GuineaPig.class ).getResultList()
204+
.chain( list -> getMutinySessionFactory().withStatelessSession( s -> {
205+
assertEquals( session, s );
206+
return s.createSelectionQuery( "from GuineaPig", GuineaPig.class ).getResultList();
207+
} ) )
208+
) );
209+
}
210+
211+
private void assertThatPigsAreEqual( GuineaPig expected, GuineaPig actual) {
212+
assertNotNull( actual );
213+
assertEquals( expected.getId(), actual.getId() );
214+
assertEquals( expected.getName(), actual.getName() );
215+
}
216+
217+
@NamedQuery(name = "findbyname", query = "from GuineaPig where name=:n")
218+
@NamedQuery(name = "updatebyname", query = "update GuineaPig set name='Y'")
219+
@NamedQuery(name = "findall", query = "from GuineaPig")
220+
221+
@Entity(name = "GuineaPig")
222+
@Table(name = "Piggy")
223+
public static class GuineaPig {
224+
@Id
225+
@GeneratedValue
226+
private Integer id;
227+
private String name;
228+
@Version
229+
private int version;
230+
231+
@ManyToOne
232+
private GuineaPig mate;
233+
234+
public GuineaPig() {
235+
}
236+
237+
public GuineaPig(String name) {
238+
this.name = name;
239+
}
240+
241+
public Integer getId() {
242+
return id;
243+
}
244+
245+
public void setId(Integer id) {
246+
this.id = id;
247+
}
248+
249+
public String getName() {
250+
return name;
251+
}
252+
253+
public void setName(String name) {
254+
this.name = name;
255+
}
256+
257+
@Override
258+
public String toString() {
259+
return id + ": " + name;
260+
}
261+
262+
@Override
263+
public boolean equals(Object o) {
264+
if ( this == o ) {
265+
return true;
266+
}
267+
if ( o == null || getClass() != o.getClass() ) {
268+
return false;
269+
}
270+
GuineaPig guineaPig = (GuineaPig) o;
271+
return Objects.equals( name, guineaPig.name );
272+
}
273+
274+
@Override
275+
public int hashCode() {
276+
return Objects.hash( name );
277+
}
278+
}
279+
}

0 commit comments

Comments
 (0)