quarkus: User methods requiring a session in Hibernate Reactive does not work for interfaces of Panache REST Data extension

Describe the bug

Two problems:

First, run curl -H 'Content-Type: application/json' localhost:8080/bot --data-binary '{"id": "bot-a", "config": {}}' , then these two commands fail:

  1. curl localhost:8080/bot throws exception, rs.getString() failed on JsonObject.
Caused by: java.lang.ClassCastException: Invalid String value type class io.vertx.core.json.JsonObject
                        at io.vertx.sqlclient.Tuple.getString(Tuple.java:410)
                        at org.hibernate.reactive.adaptor.impl.ResultSetAdaptor.getString(ResultSetAdaptor.java:80)
                        at org.hibernate.type.descriptor.jdbc.JsonJdbcType$2.doExtract(JsonJdbcType.java:140)
                        at org.hibernate.type.descriptor.jdbc.BasicExtractor.extract(BasicExtractor.java:44)
                        at org.hibernate.reactive.sql.exec.spi.ReactiveValuesResultSet.lambda$readCurrentRowValues$2(ReactiveValuesResultSet.java:145)
                        ... 35 more
  1. curl localhost:8080/bot/all2 throws exception too:
java.lang.IllegalStateException: No current Mutiny.Session found
        - no reactive session was found in the context and the context was not marked to open a new session lazily
        - you might need to annotate the business method with @WithSession
        at io.quarkus.hibernate.reactive.panache.common.runtime.SessionOperations.getSession(SessionOperations.java:155)
        at io.quarkus.hibernate.reactive.panache.common.runtime.AbstractJpaOperations.getSession(AbstractJpaOperations.java:351)
        at io.quarkus.hibernate.reactive.panache.common.runtime.AbstractJpaOperations.findAll(AbstractJpaOperations.java:179)

BotResource.java:

public interface BotResource extends PanacheEntityResource<BotEntity, String> {

    @GET
    @Path("/all2")
    @Produces("application/json")
    default Uni<List<BotEntity>> all2() {
        return BotEntity.findAll().list();
    }
}

BotEntity.java:

import io.quarkus.hibernate.reactive.panache.PanacheEntityBase;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import java.time.Instant;
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.type.SqlTypes;

@Entity
@Table(name = "bot")
public class BotEntity extends PanacheEntityBase {

    @Id
    @Column(length = 24, nullable = false)
    public String id;

    @Enumerated(EnumType.STRING)
    @Column(length = 8, nullable = false, columnDefinition = "VARCHAR(8) DEFAULT 'DRAFT'")
    public Status status = Status.DRAFT;

    @Column(name = "created_at", insertable = false, updatable = false,
            nullable = false, columnDefinition = "DATETIME DEFAULT current_timestamp")
    public Instant createdAt;

    @Column(name = "updated_at", insertable = false, updatable = false,
            nullable = false, columnDefinition = "DATETIME DEFAULT current_timestamp ON UPDATE current_timestamp")
    public Instant updatedAt;

    @JdbcTypeCode(SqlTypes.JSON)
    @Column(nullable = false)
    public BotConfig config;

    public static enum Status {
        DRAFT, REVIEW, REJECTED, APPROVED, DELETED
    }
}

BotConfig.java

public class BotConfig {

    public String name;
}

Expected behavior

Doesn’t throw exception.

Actual behavior

Throws exception.

How to Reproduce?

No response

Output of uname -a or ver

Darwin xxx 22.4.0 Darwin Kernel Version 22.4.0: Mon Mar 6 21:00:17 PST 2023; root:xnu-8796.101.5~3/RELEASE_X86_64 x86_64

Output of java -version

OpenJDK 64-Bit Server VM Temurin-17+35 (build 17+35, mixed mode, sharing)

GraalVM version (if different from Java)

No response

Quarkus version or git rev

3.1

Build tool (ie. output of mvnw --version or gradlew --version)

Apache Maven 3.8.8 (4c87b05d9aedce574290d1acc98575ed5eb6cd39)

Additional information

No response

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 20 (19 by maintainers)

Commits related to this issue

Most upvoted comments

I don’t think the two issues you mentioned are related to the PanacheEntityResource interface, but to the Hibernate Reactive:

  • About the endpoint curl localhost:8080/bot/all2, the problem is that the WithSession annotation is ignored when it’s annotated in methods of an interface. If you move this method to a class resource, it will work. Another approach is to directly use the Mutiny session as follows:
public interface BotResource extends PanacheEntityResource<BotEntity, String> {

    @GET
    @Path("/all2")
    @Produces("application/json")
    default Uni<List<BotEntity>> all2() {
        Mutiny.SessionFactory sessionFactory = CDI.current().select(Mutiny.SessionFactory.class).get();
        return sessionFactory.withSession(s -> s.find(BotEntity.class));
    }
}

Is there any limitation about why this annotation does not work in methods part of an interface? Maybe @mkouba can help here.

  • About the another issue, this seems to be related to lack of support of @JdbcTypeCode(SqlTypes.JSON).

It’s definetively odd that you can create a new entity, and it fails when getting the list of entities.

@DavideD @Sanne can you give some light about the @JdbcTypeCode(SqlTypes.JSON) usage here? Does it supported? Is it correctly configured?

https://github.com/quarkusio/quarkus/pull/34542 should fix this issue. The @WithSessionOnDemand fixes the issue, tho @mkouba please take a quickly look into this just in case you spot something else to improve/amend/cover.