diff --git a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/mutiny/Mutiny.java b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/mutiny/Mutiny.java index aab884e76..71048e5b9 100644 --- a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/mutiny/Mutiny.java +++ b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/mutiny/Mutiny.java @@ -2269,6 +2269,31 @@ default Uni withStatelessTransaction(Function> w */ Statistics getStatistics(); + /** + * Return the current instance of {@link Session}, if any. + * A current session exists only when this method is called + * from within an invocation of {@link #withSession(Function)} + * or {@link #withTransaction(Function)}. + * + * @return the current instance, if any, or {@code null} + * + * @since 3.0 + */ + Session getCurrentSession(); + + /** + * Return the current instance of {@link Session}, if any. + * A current session exists only when this method is called + * from within an invocation of + * {@link #withStatelessSession(Function)} or + * {@link #withStatelessTransaction(Function)}. + * + * @return the current instance, if any, or {@code null} + * + * @since 3.0 + */ + StatelessSession getCurrentStatelessSession(); + /** * Destroy the session factory and clean up its connection pool. */ diff --git a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/mutiny/impl/MutinySessionFactoryImpl.java b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/mutiny/impl/MutinySessionFactoryImpl.java index f21bed53b..46a71b0b8 100644 --- a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/mutiny/impl/MutinySessionFactoryImpl.java +++ b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/mutiny/impl/MutinySessionFactoryImpl.java @@ -148,6 +148,16 @@ private CompletionStage connection(String tenantId) { : connectionPool.getConnection( tenantId ); } + @Override + public Mutiny.Session getCurrentSession() { + return context.get( contextKeyForSession ); + } + + @Override + public Mutiny.StatelessSession getCurrentStatelessSession() { + return context.get( contextKeyForStatelessSession ); + } + @Override public Uni withSession(Function> work) { Objects.requireNonNull( work, "parameter 'work' is required" ); diff --git a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/stage/Stage.java b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/stage/Stage.java index 7219501bc..a97b05e56 100644 --- a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/stage/Stage.java +++ b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/stage/Stage.java @@ -2273,6 +2273,31 @@ default CompletionStage withStatelessTransaction(Function connection(String tenantId) { : connectionPool.getConnection( tenantId ); } + @Override + public Stage.Session getCurrentSession() { + return context.get( contextKeyForSession ); + } + + @Override + public Stage.StatelessSession getCurrentStatelessSession() { + return context.get( contextKeyForStatelessSession ); + } + @Override public CompletionStage withSession(Function> work) { Objects.requireNonNull( work, "parameter 'work' is required" ); diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/MutinySessionTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/MutinySessionTest.java index fb8c7e1f1..bf46f835a 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/MutinySessionTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/MutinySessionTest.java @@ -27,12 +27,7 @@ import jakarta.persistence.metamodel.EntityType; import static java.util.concurrent.TimeUnit.MINUTES; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.Assertions.*; @Timeout(value = 10, timeUnit = MINUTES) @@ -668,6 +663,38 @@ public void testForceFlushWithDelete(VertxTestContext context) { ); } + @Test + public void testCurrentSession(VertxTestContext context) { + test( context, + getMutinySessionFactory().withSession(session -> + getMutinySessionFactory().withSession(s -> { + assertEquals(session, s); + Mutiny.Session currentSession = getMutinySessionFactory().getCurrentSession(); + assertNotNull(currentSession); + assertTrue(currentSession.isOpen()); + assertEquals(session, currentSession); + return Uni.createFrom().voidItem(); + }).invoke(() -> assertNotNull(getMutinySessionFactory().getCurrentSession())) + ).invoke(() -> assertNull(getMutinySessionFactory().getCurrentSession())) + ); + } + + @Test + public void testCurrentStatelessSession(VertxTestContext context) { + test( context, + getMutinySessionFactory().withStatelessSession(session -> + getMutinySessionFactory().withStatelessSession(s -> { + assertEquals(session, s); + Mutiny.StatelessSession currentSession = getMutinySessionFactory().getCurrentStatelessSession(); + assertNotNull(currentSession); + assertTrue(currentSession.isOpen()); + assertEquals(session, currentSession); + return Uni.createFrom().voidItem(); + }).invoke(() -> assertNotNull(getMutinySessionFactory().getCurrentStatelessSession())) + ).invoke(() -> assertNull(getMutinySessionFactory().getCurrentStatelessSession())) + ); + } + private void assertThatPigsAreEqual(GuineaPig expected, GuineaPig actual) { assertNotNull( actual ); assertEquals( expected.getId(), actual.getId() ); diff --git a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/ReactiveSessionTest.java b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/ReactiveSessionTest.java index 78494bd1c..ed0c724f1 100644 --- a/hibernate-reactive-core/src/test/java/org/hibernate/reactive/ReactiveSessionTest.java +++ b/hibernate-reactive-core/src/test/java/org/hibernate/reactive/ReactiveSessionTest.java @@ -32,12 +32,7 @@ import static java.util.concurrent.TimeUnit.MINUTES; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; @Timeout(value = 10, timeUnit = MINUTES) @@ -969,6 +964,42 @@ context, openSession() ); } + @Test + public void testCurrentSession(VertxTestContext context) { + test( context, + getSessionFactory().withSession(session -> + getSessionFactory().withSession(s -> { + assertEquals(session, s); + Stage.Session currentSession = getSessionFactory().getCurrentSession(); + assertNotNull(currentSession); + assertTrue(currentSession.isOpen()); + assertEquals(session, currentSession); + return CompletionStages.voidFuture(); + }) + .thenAccept(v -> assertNotNull(getSessionFactory().getCurrentSession())) + ) + .thenAccept(v -> assertNull(getSessionFactory().getCurrentSession())) + ); + } + + @Test + public void testCurrentStatelessSession(VertxTestContext context) { + test( context, + getSessionFactory().withStatelessSession(session -> + getSessionFactory().withStatelessSession(s -> { + assertEquals(session, s); + Stage.StatelessSession currentSession = getSessionFactory().getCurrentStatelessSession(); + assertNotNull(currentSession); + assertTrue(currentSession.isOpen()); + assertEquals(session, currentSession); + return CompletionStages.voidFuture(); + }) + .thenAccept(v -> assertNotNull(getSessionFactory().getCurrentStatelessSession())) + ) + .thenAccept(v -> assertNull(getSessionFactory().getCurrentStatelessSession())) + ); + } + private void assertThatPigsAreEqual(GuineaPig expected, GuineaPig actual) { assertNotNull( actual ); assertEquals( expected.getId(), actual.getId() );