quarkusquarkus-panachequarkus-rest-clientquarkus-reactivequarkus-hibernate-reactive

Quarkus kotlin and reactive hibernate with panache No current Mutiny.Session found error with suspend function only


Making the findByStatusAndTypeAndLanguage function below a suspend function causes "java.lang.IllegalStateException: No current Mutiny.Session found" error, but the function above it is suspend with no errors. Removing the suspend from the repository function makes it work as intended.

@ApplicationScoped
@WithSession
public class PostRepository : PanacheRepositoryBase<Post, String> {

    suspend fun findPostById(id: String): Uni<Post> =
        findById(id) ?: throw Exception("Post with id $id not found")

    @Transactional
    suspend fun savePost(post: Post): Uni<Post> {
        post.createdOn = Instant.now()

        return persistAndFlush(post)
    }
    suspend fun findByStatusAndTypeAndLanguage(
        status: PostStatus,
        type: PostType,
        language: WrittenLanguage,
        page: Int
        ): Uni<List<Post>> {
           val posts: PanacheQuery<Post> =
               find("type = ?1 and status = ?2 and 
               writtenLanguage = ?3", type, status, language)
           return posts
                 .page(Page.of(page, 10))
                 .list()
    }
}

I'm calling them from a service class (which I'm not sure is needed), here it can be a suspend function no problem

@ApplicationScoped
@WithSession
class PostService(private val postRepository: PostRepository) {

    @Transactional
    suspend fun savePost(post: Post): Uni<Post> {
        return this.postRepository.savePost(post)
    }
    suspend fun findByStatusAndTypeAndLanguage(
        status: PostStatus,
        type: PostType,
        language: WrittenLanguage,
        page: Int
    ) = postRepository.findByStatusAndTypeAndLanguage(status, type, language, page)

}

Then finally here, where it can also be a suspend function with no issue

@Path("/{locale}/blog/")
@Produces(MediaType.APPLICATION_JSON)
@ApplicationScoped
class PostController(private val postService: PostService) {

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    suspend fun createPost(post: Post): Post {
        return postService.savePost(post).awaitSuspending()
    }


    @Path("/{pageNumber}")
    @GET
    suspend fun getPosts(locale: String, pageNumber: Int): RestResponse<List<Post>> {
        val language = if (locale == "ar") WrittenLanguage.ARABIC else WrittenLanguage.ENGLISH
        var page = pageNumber

        if (pageNumber > 0)  page -= 1
        if (pageNumber <= 0) return RestResponse.status<List<Post>>(400)
        val posts = postService.findByStatusAndTypeAndLanguage(
            PostStatus.DRAFT,
            PostType.BLOGPOST,
            language,
            page
        ).awaitSuspending()
        return RestResponse.ok(posts)
    }
}

Solution

  • https://github.com/quarkusio/quarkus/pull/34542

    You can use Panache.withSession() to bypass.