quarkus: hibernate reactive report cast error when the column contains json field

Describe the bug

the code was rewrite from hibernate jpa to hibernate reactive, the jpa works, here is my table definition

@Embeddable
public class DingCorpUserKey implements Serializable {
    @Column(name = "corp_id")
    private String corpId;
    @Column(name = "union_id")
    private String unionId;

    public DingCorpUserKey() {
    }

    public DingCorpUserKey(String corpId, String unionId) {
        this.corpId = corpId;
        this.unionId = unionId;
    }

    public String getCorpId() {
        return corpId;
    }

    public void setCorpId(String corpId) {
        this.corpId = corpId;
    }

    public String getUnionId() {
        return unionId;
    }

    public void setUnionId(String unionId) {
        this.unionId = unionId;
    }

    @Override
    public boolean equals(Object o) {
        if (o == null) return false;
        if (this == o) return true;
        if (o instanceof DingCorpUserKey key) {
            return Objects.equals(corpId, key.corpId) && Objects.equals(unionId, key.unionId);
        }
        return false;
    }

    @Override
    public int hashCode() {
        return Objects.hash(corpId, unionId);
    }
}


@Entity
@Table(name = "ding_corp_user")
public class DingCorpUser {
    @EmbeddedId
    private DingCorpUserKey dingCorpUserKey;
    @Column(name = "user_id")
    private String userId;
    @Column(name = "manager_userid")
    private String managerUserId;
    @Column(name = "hide_mobile")
    private boolean hideMobile;
    @Column(name = "job_number")
    private String jobNumber;
    @Column(name = "title")
    private String title;
    @Column(name = "exclusive_account")
    private boolean exclusiveAccount;
    @Convert(converter = IntListConverter.class)
    @Column(name = "dept_id_list")
    private List<Integer> deptIdList;
    @Convert(converter = DingDeptOrderListConverter.class)
    @Column(name = "dept_order")
    private List<DingDeptOrder> deptOrders;
    @Column(name = "active")
    private boolean active;
    @Column(name = "senior")
    private boolean senior;
    @Column(name = "admin")
    private boolean admin;
    @Column(name = "boss")
    private boolean boss;
    @Column(name = "type")
    private int type;
    @Convert(converter = DingDeptLeaderListConverter.class)
    @Column(name = "dept_leader")
    private List<DingDeptLeader> deptLeaders;
    @Convert(converter = DingUserRoleListConverter.class)
    @Column(name = "roles")
    private List<DingUserRole> roles;

    public DingCorpUser() {
    }

    public DingCorpUser(DingCorpUserKey dingCorpUserKey, String userId, String managerUserId, boolean hideMobile, String jobNumber, String title, boolean exclusiveAccount, List<Integer> deptIdList, List<DingDeptOrder> deptOrders, boolean active, boolean senior, boolean admin, boolean boss, int type, List<DingDeptLeader> deptLeaders, List<DingUserRole> roles) {
        this.dingCorpUserKey = dingCorpUserKey;
        this.userId = userId;
        this.managerUserId = managerUserId;
        this.hideMobile = hideMobile;
        this.jobNumber = jobNumber;
        this.title = title;
        this.exclusiveAccount = exclusiveAccount;
        this.deptIdList = deptIdList;
        this.deptOrders = deptOrders;
        this.active = active;
        this.senior = senior;
        this.admin = admin;
        this.boss = boss;
        this.type = type;
        this.deptLeaders = deptLeaders;
        this.roles = roles;
    }

    public DingCorpUserKey getDingCorpUserKey() {
        return dingCorpUserKey;
    }

    public void setDingCorpUserKey(DingCorpUserKey dingCorpUserKey) {
        this.dingCorpUserKey = dingCorpUserKey;
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getManagerUserId() {
        return managerUserId;
    }

    public void setManagerUserId(String managerUserId) {
        this.managerUserId = managerUserId;
    }

    public boolean isHideMobile() {
        return hideMobile;
    }

    public void setHideMobile(boolean hideMobile) {
        this.hideMobile = hideMobile;
    }

    public String getJobNumber() {
        return jobNumber;
    }

    public void setJobNumber(String jobNumber) {
        this.jobNumber = jobNumber;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public boolean isExclusiveAccount() {
        return exclusiveAccount;
    }

    public void setExclusiveAccount(boolean exclusiveAccount) {
        this.exclusiveAccount = exclusiveAccount;
    }

    public List<Integer> getDeptIdList() {
        return deptIdList;
    }

    public void setDeptIdList(List<Integer> deptIdList) {
        this.deptIdList = deptIdList;
    }

    public List<DingDeptOrder> getDeptOrders() {
        return deptOrders;
    }

    public void setDeptOrders(List<DingDeptOrder> deptOrders) {
        this.deptOrders = deptOrders;
    }

    public boolean isActive() {
        return active;
    }

    public void setActive(boolean active) {
        this.active = active;
    }

    public boolean isSenior() {
        return senior;
    }

    public void setSenior(boolean senior) {
        this.senior = senior;
    }

    public boolean isAdmin() {
        return admin;
    }

    public void setAdmin(boolean admin) {
        this.admin = admin;
    }

    public boolean isBoss() {
        return boss;
    }

    public void setBoss(boolean boss) {
        this.boss = boss;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public List<DingDeptLeader> getDeptLeaders() {
        return deptLeaders;
    }

    public void setDeptLeaders(List<DingDeptLeader> deptLeaders) {
        this.deptLeaders = deptLeaders;
    }

    public List<DingUserRole> getRoles() {
        return roles;
    }

    public void setRoles(List<DingUserRole> roles) {
        this.roles = roles;
    }
}

Expected behavior

the query execute success

Actual behavior

2022-12-19 17:17:03,366 ERROR (vert.x-eventloop-thread-0) HR000057: Failed to execute statement [select dingcorpus0_.corp_id as corp_id1_2_0_, dingcorpus0_.union_id as union_id2_2_0_, dingcorpus0_.active as active3_2_0_, dingcorpus0_.admin as admin4_2_0_, dingcorpus0_.boss as boss5_2_0_, dingcorpus0_.dept_id_list as dept_id_6_2_0_, dingcorpus0_.dept_leader as dept_lea7_2_0_, dingcorpus0_.dept_order as dept_ord8_2_0_, dingcorpus0_.exclusive_account as exclusiv9_2_0_, dingcorpus0_.hide_mobile as hide_mo10_2_0_, dingcorpus0_.job_number as job_num11_2_0_, dingcorpus0_.manager_userid as manager12_2_0_, dingcorpus0_.roles as roles13_2_0_, dingcorpus0_.senior as senior14_2_0_, dingcorpus0_.title as title15_2_0_, dingcorpus0_.type as type16_2_0_, dingcorpus0_.user_id as user_id17_2_0_ from ding_corp_user dingcorpus0_ where dingcorpus0_.corp_id=? and dingcorpus0_.union_id=?]: could not load an entity: [com.nxin.ding.domain.user.entity.DingCorpUser#component[corpId,unionId]{unionId=DnWxeNUxqKbiS9WOXwUjoTwiEiE, corpId=ding8d4a742ff92d6ef3acaaa37764f94726}]: java.util.concurrent.CompletionException: java.lang.ClassCastException: Invalid String value type class io.vertx.core.json.JsonArray
        at java.base/java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:315)
        at java.base/java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:320)
        at java.base/java.util.concurrent.CompletableFuture$UniCompose.tryFire(CompletableFuture.java:1159)
        at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)
        at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2147)
        at io.vertx.core.Future.lambda$toCompletionStage$3(Future.java:384)
        at io.vertx.core.impl.future.FutureImpl$3.onSuccess(FutureImpl.java:141)
        at io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:60)
        at io.vertx.core.impl.future.FutureImpl.tryComplete(FutureImpl.java:211)
        at io.vertx.core.impl.future.PromiseImpl.tryComplete(PromiseImpl.java:23)
        at io.vertx.sqlclient.impl.QueryResultBuilder.tryComplete(QueryResultBuilder.java:100)
        at io.vertx.sqlclient.impl.QueryResultBuilder.tryComplete(QueryResultBuilder.java:34)
        at io.vertx.core.Promise.complete(Promise.java:66)
        at io.vertx.core.Promise.handle(Promise.java:51)
        at io.vertx.core.Promise.handle(Promise.java:29)
        at io.vertx.core.impl.future.FutureImpl$3.onSuccess(FutureImpl.java:141)
        at io.vertx.core.impl.future.FutureBase.lambda$emitSuccess$0(FutureBase.java:54)
        at io.vertx.core.impl.EventLoopContext.execute(EventLoopContext.java:86)
        at io.vertx.core.impl.DuplicatedContext.execute(DuplicatedContext.java:163)
        at io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:51)
        at io.vertx.core.impl.future.FutureImpl.tryComplete(FutureImpl.java:211)
        at io.vertx.core.impl.future.PromiseImpl.tryComplete(PromiseImpl.java:23)
        at io.vertx.core.impl.future.PromiseImpl.onSuccess(PromiseImpl.java:49)
        at io.vertx.core.impl.future.PromiseImpl.handle(PromiseImpl.java:41)
        at io.vertx.core.impl.future.PromiseImpl.handle(PromiseImpl.java:23)
        at io.vertx.sqlclient.impl.command.CommandResponse.fire(CommandResponse.java:46)
        at io.vertx.sqlclient.impl.SocketConnectionBase.handleMessage(SocketConnectionBase.java:292)
        at io.vertx.sqlclient.impl.SocketConnectionBase.lambda$init$0(SocketConnectionBase.java:105)
        at io.vertx.core.impl.EventLoopContext.emit(EventLoopContext.java:55)
        at io.vertx.core.impl.ContextBase.emit(ContextBase.java:239)
        at io.vertx.core.net.impl.NetSocketImpl.handleMessage(NetSocketImpl.java:390)
        at io.vertx.core.net.impl.ConnectionBase.read(ConnectionBase.java:157)
        at io.vertx.core.net.impl.VertxHandler.channelRead(VertxHandler.java:153)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
        at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436)
        at io.vertx.mysqlclient.impl.codec.MySQLEncoder.handleCommandResponse(MySQLEncoder.java:63)
        at io.vertx.mysqlclient.impl.codec.QueryCommandBaseCodec.handleAllResultsetDecodingCompleted(QueryCommandBaseCodec.java:175)
        at io.vertx.mysqlclient.impl.codec.ExtendedQueryCommandBaseCodec.handleAllResultsetDecodingCompleted(ExtendedQueryCommandBaseCodec.java:51)
        at io.vertx.mysqlclient.impl.codec.QueryCommandBaseCodec.handleSingleResultsetDecodingCompleted(QueryCommandBaseCodec.java:136)
        at io.vertx.mysqlclient.impl.codec.QueryCommandBaseCodec.handleRows(QueryCommandBaseCodec.java:124)
        at io.vertx.mysqlclient.impl.codec.QueryCommandBaseCodec.decodePayload(QueryCommandBaseCodec.java:66)
        at io.vertx.mysqlclient.impl.codec.ExtendedQueryCommandCodec.decodePayload(ExtendedQueryCommandCodec.java:108)
        at io.vertx.mysqlclient.impl.codec.MySQLDecoder.decodePackets(MySQLDecoder.java:72)
        at io.vertx.mysqlclient.impl.codec.MySQLDecoder.channelRead(MySQLDecoder.java:48)
        at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
        at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:346)
        at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:318)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
        at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
        at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
        at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
        at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788)
        at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724)
        at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650)
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562)
        at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
        at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.ClassCastException: Invalid String value type class io.vertx.core.json.JsonArray
        at io.vertx.sqlclient.Tuple.getString(Tuple.java:410)
        at io.vertx.sqlclient.Row.getString(Row.java:188)
        at org.hibernate.reactive.adaptor.impl.ResultSetAdaptor.getString(ResultSetAdaptor.java:183)
        at org.hibernate.type.descriptor.sql.VarcharTypeDescriptor$2.doExtract(VarcharTypeDescriptor.java:62)
        at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:47)
        at org.hibernate.type.descriptor.converter.AttributeConverterSqlTypeDescriptorAdapter$2.extract(AttributeConverterSqlTypeDescriptorAdapter.java:121)
        at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:257)
        at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:253)
        at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:243)
        at org.hibernate.type.AbstractStandardBasicType.hydrate(AbstractStandardBasicType.java:329)
        at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:3214)
        at org.hibernate.persister.entity.Loadable.hydrate(Loadable.java:94)
        at org.hibernate.loader.plan.exec.process.internal.EntityReferenceInitializerImpl.loadFromResultSet(EntityReferenceInitializerImpl.java:342)
        at org.hibernate.loader.plan.exec.process.internal.EntityReferenceInitializerImpl.hydrateEntityState(EntityReferenceInitializerImpl.java:269)
        at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.readRow(AbstractRowReader.java:80)
        at org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl.extractRows(ResultSetProcessorImpl.java:157)
        at org.hibernate.reactive.loader.entity.impl.ReactivePlanEntityLoader$ReactiveLoadPlanBasedResultSetProcessor.reactiveExtractResults(ReactivePlanEntityLoader.java:352)
        at org.hibernate.reactive.loader.ReactiveLoader.reactiveProcessResultSet(ReactiveLoader.java:154)
        at org.hibernate.reactive.loader.ReactiveLoader.lambda$doReactiveQueryAndInitializeNonLazyCollections$0(ReactiveLoader.java:81)
        at java.base/java.util.concurrent.CompletableFuture$UniCompose.tryFire(CompletableFuture.java:1150)
        ... 65 more

How to Reproduce?

No response

Output of uname -a or ver

Linux ding-isv01 3.10.0-1160.31.1.el7.x86_64 #1 SMP Thu Jun 10 13:32:12 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

Output of java -version

OpenJDK Runtime Environment GraalVM CE 22.3.0 (build 17.0.5+8-jvmci-22.3-b08) OpenJDK 64-Bit Server VM GraalVM CE 22.3.0 (build 17.0.5+8-jvmci-22.3-b08, mixed mode, sharing)

GraalVM version (if different from Java)

22.3.0

Quarkus version or git rev

2.15.0

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

gradle 7.6.0

Additional information

No response

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 28 (10 by maintainers)

Most upvoted comments

I’m going to close this issue. This doesn’t seem a bug after all. But feel free to ask more questions if you have some