Skip to content

Commit 9736346

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

File tree

2 files changed

+252
-2
lines changed

2 files changed

+252
-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: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
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 testStatelessSessionCriteria(VertxTestContext context) {
126+
GuineaPig pig = new GuineaPig( "Aloi" );
127+
GuineaPig mate = new GuineaPig("Aloina");
128+
pig.mate = mate;
129+
130+
CriteriaBuilder cb = getSessionFactory().getCriteriaBuilder();
131+
132+
CriteriaQuery<GuineaPig> query = cb.createQuery( GuineaPig.class );
133+
Root<GuineaPig> gp = query.from( GuineaPig.class );
134+
query.where( cb.equal( gp.get( "name" ), cb.parameter( String.class, "n" ) ) );
135+
query.orderBy( cb.asc( gp.get( "name" ) ) );
136+
137+
test( context, getMutinySessionFactory().openStatelessSession()
138+
.chain( ss -> ss.insert(mate)
139+
.chain( v -> ss.insert(pig) )
140+
.chain( v -> ss.createQuery( query )
141+
.setParameter( "n", pig.name )
142+
.getResultList() )
143+
.invoke( list -> {
144+
assertFalse( list.isEmpty() );
145+
assertEquals( 1, list.size() );
146+
assertThatPigsAreEqual( pig, list.get( 0 ) );
147+
} )
148+
.chain( v -> ss.close() ) )
149+
);
150+
}
151+
152+
@Test
153+
public void testTransactionPropagation(VertxTestContext context) {
154+
test( context, getMutinySessionFactory().withStatelessSession(
155+
session -> session.withTransaction( transaction -> session.createSelectionQuery( "from GuineaPig", GuineaPig.class )
156+
.getResultList()
157+
.chain( list -> {
158+
assertNotNull( session.currentTransaction() );
159+
assertFalse( session.currentTransaction().isMarkedForRollback() );
160+
session.currentTransaction().markForRollback();
161+
assertTrue( session.currentTransaction().isMarkedForRollback() );
162+
assertTrue( transaction.isMarkedForRollback() );
163+
return session.withTransaction( t -> {
164+
assertTrue( t.isMarkedForRollback() );
165+
return session.createSelectionQuery( "from GuineaPig", GuineaPig.class ).getResultList();
166+
} );
167+
} ) )
168+
) );
169+
}
170+
171+
@Test
172+
public void testSessionPropagation(VertxTestContext context) {
173+
test( context, getMutinySessionFactory().withStatelessSession(
174+
session -> session.createSelectionQuery( "from GuineaPig", GuineaPig.class ).getResultList()
175+
.chain( list -> getMutinySessionFactory().withStatelessSession( s -> {
176+
assertEquals( session, s );
177+
return s.createSelectionQuery( "from GuineaPig", GuineaPig.class ).getResultList();
178+
} ) )
179+
) );
180+
}
181+
182+
private void assertThatPigsAreEqual( GuineaPig expected, GuineaPig actual) {
183+
assertNotNull( actual );
184+
assertEquals( expected.getId(), actual.getId() );
185+
assertEquals( expected.getName(), actual.getName() );
186+
}
187+
188+
@NamedQuery(name = "findbyname", query = "from GuineaPig where name=:n")
189+
@NamedQuery(name = "updatebyname", query = "update GuineaPig set name='Y'")
190+
@NamedQuery(name = "findall", query = "from GuineaPig")
191+
192+
@Entity(name = "GuineaPig")
193+
@Table(name = "Piggy")
194+
public static class GuineaPig {
195+
@Id
196+
@GeneratedValue
197+
private Integer id;
198+
private String name;
199+
@Version
200+
private int version;
201+
202+
@ManyToOne
203+
private GuineaPig mate;
204+
205+
public GuineaPig() {
206+
}
207+
208+
public GuineaPig(String name) {
209+
this.name = name;
210+
}
211+
212+
public Integer getId() {
213+
return id;
214+
}
215+
216+
public void setId(Integer id) {
217+
this.id = id;
218+
}
219+
220+
public String getName() {
221+
return name;
222+
}
223+
224+
public void setName(String name) {
225+
this.name = name;
226+
}
227+
228+
@Override
229+
public String toString() {
230+
return id + ": " + name;
231+
}
232+
233+
@Override
234+
public boolean equals(Object o) {
235+
if ( this == o ) {
236+
return true;
237+
}
238+
if ( o == null || getClass() != o.getClass() ) {
239+
return false;
240+
}
241+
GuineaPig guineaPig = (GuineaPig) o;
242+
return Objects.equals( name, guineaPig.name );
243+
}
244+
245+
@Override
246+
public int hashCode() {
247+
return Objects.hash( name );
248+
}
249+
}
250+
}

0 commit comments

Comments
 (0)