Skip to content

Commit 5d48442

Browse files
committed
Test
1 parent e67c91b commit 5d48442

File tree

3 files changed

+188
-0
lines changed

3 files changed

+188
-0
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package io.quarkus.it.panache.reactive;
2+
3+
import io.quarkus.hibernate.reactive.panache.PanacheEntityBase;
4+
import jakarta.persistence.Entity;
5+
import jakarta.persistence.Id;
6+
7+
@Entity
8+
public class Counter extends PanacheEntityBase {
9+
10+
@Id
11+
private Long id;
12+
private int count = 0;
13+
14+
public Counter() {
15+
}
16+
17+
public Counter(long id) {
18+
this.id = id;
19+
}
20+
21+
public Long getId() {
22+
return id;
23+
}
24+
25+
public int getCount() {
26+
return count;
27+
}
28+
29+
@Override
30+
public String toString() {
31+
return String.valueOf(count);
32+
}
33+
34+
public void increase() {
35+
this.count++;
36+
}
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package io.quarkus.it.panache.reactive;
2+
3+
import org.hibernate.reactive.mutiny.Mutiny;
4+
5+
import org.junit.jupiter.api.Assertions;
6+
7+
import io.quarkus.hibernate.reactive.panache.Panache;
8+
import io.quarkus.hibernate.reactive.panache.common.WithTransaction;
9+
import io.smallrye.mutiny.Uni;
10+
import jakarta.enterprise.context.ApplicationScoped;
11+
import jakarta.inject.Inject;
12+
import java.util.function.Function;
13+
import java.util.function.Supplier;
14+
15+
import static jakarta.persistence.LockModeType.PESSIMISTIC_WRITE;
16+
17+
/**
18+
* The goal if this class is to test the usage of {@link WithTransaction},
19+
* you should not use {@link io.quarkus.hibernate.reactive.panache.Panache#withTransaction(Supplier)}
20+
* nor {@link org.hibernate.reactive.mutiny.Mutiny.SessionFactory#withTransaction(Function)}
21+
*/
22+
@ApplicationScoped
23+
@WithTransaction
24+
public class WithTransactionCounterBean {
25+
26+
private static final Long ID_COUNTER = 42L;
27+
28+
@Inject
29+
Mutiny.SessionFactory sessionFactory;
30+
31+
public Uni<Counter> createOrResetCounter() {
32+
final Counter counter = new Counter(ID_COUNTER);
33+
return sessionFactory.withStatelessSession(session -> session
34+
.upsert(counter)
35+
.replaceWith(counter)
36+
);
37+
}
38+
39+
public Uni<Counter> increaseCounterWithHR() {
40+
return sessionFactory.withSession(session -> session
41+
.find(Counter.class, ID_COUNTER, PESSIMISTIC_WRITE)
42+
.invoke(Counter::increase)
43+
);
44+
}
45+
46+
public Uni<Counter> increaseCounterWithPanache() {
47+
return Counter
48+
.<Counter> findById(ID_COUNTER, PESSIMISTIC_WRITE)
49+
.invoke(Counter::increase);
50+
}
51+
52+
public Uni<Void> assertThatSessionsAreEqual() {
53+
return sessionFactory.withSession(hrSession -> Panache
54+
.getSession().chain(panacheSession -> {
55+
if (panacheSession != hrSession) {
56+
return Uni.createFrom().failure(new AssertionError("Sessions are different!"));
57+
}
58+
return Uni.createFrom().voidItem();
59+
})
60+
);
61+
}
62+
63+
public Uni<Counter> findCounter() {
64+
return sessionFactory.withSession(session -> session
65+
.find(Counter.class, ID_COUNTER)
66+
);
67+
}
68+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package io.quarkus.it.panache.reactive;
2+
3+
import org.junit.jupiter.api.BeforeEach;
4+
import org.junit.jupiter.api.Test;
5+
6+
import io.quarkus.test.junit.QuarkusTest;
7+
import io.smallrye.mutiny.Uni;
8+
import jakarta.inject.Inject;
9+
import java.util.ArrayList;
10+
import java.util.List;
11+
import java.util.function.Supplier;
12+
13+
import static io.quarkus.vertx.VertxContextSupport.subscribeAndAwait;
14+
import static org.assertj.core.api.Assertions.assertThat;
15+
import static org.junit.jupiter.api.Assertions.fail;
16+
17+
/**
18+
* Hibernate Reactive and Panache store the created sessions in a local Vert.x context,
19+
* and we need to make sure that they won't get lost.
20+
* See issue <a href="https://github.com/quarkusio/quarkus/issues/47314">47314</a>
21+
*
22+
* @see io.quarkus.hibernate.reactive.panache.common.runtime.SessionOperations
23+
* @see io.quarkus.hibernate.reactive.panache.common.WithTransaction
24+
*/
25+
@QuarkusTest
26+
public class WithTransactionTest {
27+
// How many times we want to increase the counter
28+
private static final int INCREASES_NUM = 10;
29+
30+
@Inject
31+
WithTransactionCounterBean counterBean;
32+
33+
@BeforeEach
34+
public void createOrResetCounter() throws Throwable {
35+
subscribeAndAwait(counterBean::createOrResetCounter);
36+
}
37+
38+
@Test
39+
void increaseCounterWithHibernateReactive() throws Throwable {
40+
subscribeAndAwait(counterBean::increaseCounterWithHR);
41+
Counter counter = subscribeAndAwait(counterBean::findCounter);
42+
43+
assertThat(counter.getCount()).isEqualTo(1);
44+
}
45+
46+
@Test
47+
void increaseCounterWithPanache() throws Throwable {
48+
subscribeAndAwait(counterBean::increaseCounterWithPanache);
49+
Counter counter = subscribeAndAwait(counterBean::findCounter);
50+
51+
assertThat(counter.getCount()).isEqualTo(1);
52+
}
53+
54+
@Test
55+
void shouldReuseExistingSessions() throws Throwable {
56+
subscribeAndAwait(counterBean::assertThatSessionsAreEqual);
57+
}
58+
59+
@Test
60+
void increaseCounter() throws Throwable {
61+
List<Supplier<Uni<Counter>>> suppliers = new ArrayList<>();
62+
for (int i = 0; i < INCREASES_NUM; i++) {
63+
suppliers.add(() -> counterBean.increaseCounterWithHR());
64+
}
65+
66+
final List<Counter> results = new ArrayList<>();
67+
suppliers.stream()
68+
.parallel()
69+
.forEach(uni -> increaseCounter(uni, results));
70+
71+
final Counter dbCounter = subscribeAndAwait(() -> counterBean.findCounter());
72+
assertThat(dbCounter.getCount()).isEqualTo(INCREASES_NUM);
73+
}
74+
75+
private static void increaseCounter(Supplier<Uni<Counter>> func, List<Counter> counters) {
76+
try {
77+
final var counter = subscribeAndAwait(func);
78+
counters.add(counter);
79+
} catch (final Throwable e) {
80+
fail(e);
81+
}
82+
}
83+
}

0 commit comments

Comments
 (0)