Skip to content

Commit 58354ea

Browse files
committed
[#2926] Test error when there's an unexpected transaction
1 parent cd7f104 commit 58354ea

File tree

1 file changed

+189
-0
lines changed

1 file changed

+189
-0
lines changed
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.reactive;
6+
7+
import java.util.Collection;
8+
import java.util.List;
9+
import java.util.concurrent.CompletionStage;
10+
11+
import org.hibernate.reactive.pool.ReactiveConnection;
12+
import org.hibernate.reactive.stage.Stage;
13+
import org.hibernate.reactive.stage.impl.StageSessionImpl;
14+
import org.hibernate.reactive.util.impl.CompletionStages;
15+
16+
import org.junit.jupiter.api.Test;
17+
18+
import io.vertx.junit5.VertxTestContext;
19+
import jakarta.persistence.Entity;
20+
import jakarta.persistence.Id;
21+
22+
import static org.assertj.core.api.Assertions.assertThat;
23+
import static org.hibernate.reactive.testing.ReactiveAssertions.assertThrown;
24+
25+
public class NoLiveTransactionValidationErrorTest extends BaseReactiveTest {
26+
27+
@Override
28+
protected Collection<Class<?>> annotatedEntities() {
29+
return List.of( Comic.class );
30+
}
31+
32+
@Test
33+
public void beginTransactionError(VertxTestContext context) {
34+
final Stage.Session[] session = { null };
35+
test( context, assertThrown( IllegalStateException.class, getSessionFactory()
36+
.openSession()
37+
.thenCompose( s -> {
38+
session[0] = s;
39+
ReactiveConnection connection = reactiveConnection( s );
40+
return connection.beginTransaction()
41+
.thenCompose( t1 -> connection.beginTransaction() );
42+
} )
43+
)
44+
.thenAccept( e -> {
45+
assertThat( e )
46+
.hasMessageContaining( "HR000091" )
47+
.hasMessageContaining( "Can't begin a new transaction" );
48+
} )
49+
.handle( CompletionStages::handle )
50+
// We try to close the session we opened
51+
.thenCompose( assertionHandler -> close( session[0] )
52+
.thenCompose( assertionHandler::getResultAsCompletionStage ) )
53+
);
54+
}
55+
56+
// Try to close the session ignoring any error
57+
private static CompletionStage<Void> close( Stage.Session session) {
58+
return closeSession( session ).handle( (unused, throwable) -> null );
59+
}
60+
61+
private static ReactiveConnection reactiveConnection(Stage.Session s) {
62+
return ( (StageSessionImpl) s ).getReactiveConnection();
63+
}
64+
65+
@Test
66+
public void rollbackOnCloseWithStage(VertxTestContext context) {
67+
Comic beneath = new Comic( "979-8887241081", "Beneath The Trees Where Nobody Sees" );
68+
69+
test(
70+
context,
71+
assertThrown( IllegalStateException.class, getSessionFactory()
72+
.withTransaction( s -> s
73+
.persist( beneath )
74+
.thenCompose( v -> s.flush() )
75+
// Close the connection before committing
76+
.thenCompose( v -> s.close() )
77+
)
78+
)
79+
.thenAccept( e -> assertThat( e )
80+
.hasMessageContaining( "HR000090" )
81+
.hasMessageContaining( "closing the connection" )
82+
)
83+
.thenCompose( v -> getSessionFactory()
84+
.withTransaction( s -> s.find( Comic.class, beneath.isbn ) )
85+
)
86+
.thenAccept( result -> assertThat( result )
87+
.as( "The persist should have been roll backed" )
88+
.isNull() )
89+
);
90+
}
91+
92+
@Test
93+
public void rollbackOnErrorWithStage(VertxTestContext context) {
94+
Comic beneath = new Comic( "979-8887241081", "Beneath The Trees Where Nobody Sees" );
95+
final RuntimeException ohNo = new RuntimeException( "Oh, no!" );
96+
test(
97+
context,
98+
assertThrown( RuntimeException.class, getSessionFactory()
99+
.withTransaction( s -> s
100+
.persist( beneath )
101+
.thenCompose( v -> s.flush() )
102+
// Close the connection before committing
103+
.thenAccept( v -> {
104+
throw ohNo;
105+
} )
106+
)
107+
)
108+
.thenAccept( e -> assertThat( e ).hasMessageContaining( ohNo.getMessage() ) )
109+
.thenCompose( v -> getSessionFactory()
110+
.withTransaction( s -> s.find( Comic.class, beneath.isbn ) )
111+
)
112+
.thenAccept( result -> assertThat( result )
113+
.as( "The persist should have been roll backed" )
114+
.isNull() )
115+
);
116+
}
117+
118+
@Test
119+
public void rollbackOnClose(VertxTestContext context) {
120+
Comic beneath = new Comic( "979-8887241081", "Beneath The Trees Where Nobody Sees" );
121+
122+
test(
123+
context,
124+
assertThrown( IllegalStateException.class, getMutinySessionFactory()
125+
.withTransaction( s -> s
126+
.persist( beneath )
127+
.call( s::flush )
128+
// Close the connection before committing
129+
.call( s::close )
130+
)
131+
)
132+
.invoke( e -> assertThat( e )
133+
.hasMessageContaining( "HR000090" )
134+
.hasMessageContaining( "closing the connection" )
135+
)
136+
.chain( () -> getMutinySessionFactory()
137+
.withTransaction( s -> s.find( Comic.class, beneath.isbn ) )
138+
)
139+
.invoke( result -> assertThat( result )
140+
.as( "The persist should have been roll backed" )
141+
.isNull() )
142+
);
143+
}
144+
145+
@Test
146+
public void rollbackOnError(VertxTestContext context) {
147+
Comic beneath = new Comic( "979-8887241081", "Beneath The Trees Where Nobody Sees" );
148+
final RuntimeException ohNo = new RuntimeException( "Oh, no!" );
149+
test(
150+
context,
151+
assertThrown( RuntimeException.class, getMutinySessionFactory()
152+
.withTransaction( s -> s
153+
.persist( beneath )
154+
.call( s::flush )
155+
.chain( () -> {
156+
throw ohNo;
157+
} )
158+
)
159+
)
160+
.invoke( e -> assertThat( e ).hasMessageContaining( ohNo.getMessage() ) )
161+
.chain( () -> getMutinySessionFactory()
162+
.withTransaction( s -> s.find( Comic.class, beneath.isbn ) )
163+
)
164+
.invoke( result -> assertThat( result )
165+
.as( "The persist should have been roll backed" )
166+
.isNull() )
167+
);
168+
}
169+
170+
@Entity
171+
public static class Comic {
172+
@Id
173+
public String isbn;
174+
public String title;
175+
176+
public Comic() {
177+
}
178+
179+
public Comic(String iban, String title) {
180+
this.isbn = iban;
181+
this.title = title;
182+
}
183+
184+
@Override
185+
public String toString() {
186+
return isbn + ":" + title;
187+
}
188+
}
189+
}

0 commit comments

Comments
 (0)