Skip to content

Vertx client doesn't deal correctly with a byte array set to nullΒ #1477

@wjglerum

Description

@wjglerum

Questions

After updating our application to Quarkus 3.16.4 see https://github.com/quarkusio/quarkus/releases/tag/3.16.4 we noticed that we got a test failure for the case when we try to persist a Hibernate entity that has a byte array field set to null. This used to work before upgrading to Quarkus 3.16.4 which also upgrades Vert.x to 4.5.11

We get the following exception:

java.lang.NullPointerException: Cannot invoke "Object.getClass()" because "value" is null
	at io.vertx.sqlclient.impl.ErrorMessageFactory.buildWhenArgumentsTypeNotMatched(ErrorMessageFactory.java:23)
	at io.vertx.pgclient.impl.codec.PgParamDesc.prepare(PgParamDesc.java:57)
	at io.vertx.pgclient.impl.codec.PgPreparedStatement.prepare(PgPreparedStatement.java:57)
	at io.vertx.sqlclient.impl.command.ExtendedQueryCommand.prepare(ExtendedQueryCommand.java:122)
	at io.vertx.sqlclient.impl.SocketConnectionBase.lambda$prepareCommand$4(SocketConnectionBase.java:295)
	at io.vertx.sqlclient.impl.command.CommandResponse.fire(CommandResponse.java:46)
	at io.vertx.sqlclient.impl.SocketConnectionBase.handleMessage(SocketConnectionBase.java:324)
	at io.vertx.pgclient.impl.PgSocketConnection.handleMessage(PgSocketConnection.java:114)
	at io.vertx.sqlclient.impl.SocketConnectionBase.lambda$init$0(SocketConnectionBase.java:137)
	at io.vertx.core.impl.ContextImpl.emit(ContextImpl.java:342)
	at io.vertx.core.impl.ContextImpl.emit(ContextImpl.java:335)
	at io.vertx.core.net.impl.NetSocketImpl.handleMessage(NetSocketImpl.java:389)
	at io.vertx.core.net.impl.ConnectionBase.read(ConnectionBase.java:159)
	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.pgclient.impl.codec.PgDecoder.fireCommandResponse(PgDecoder.java:52)
	at io.vertx.pgclient.impl.codec.PgCommandCodec.handleReadyForQuery(PgCommandCodec.java:133)
	at io.vertx.pgclient.impl.codec.PrepareStatementCommandCodec.handleReadyForQuery(PrepareStatementCommandCodec.java:96)
	at io.vertx.pgclient.impl.codec.PgDecoder.decodeReadyForQuery(PgDecoder.java:248)
	at io.vertx.pgclient.impl.codec.PgDecoder.channelRead(PgDecoder.java:107)
	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.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1357)
	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:868)
	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:1583)

Which can be resolved to setting the entity field to an empty byte array instead of null. Then it is able to persist the entity.

Version

Vert.x 4.5.11

Context

Quarkus app with Hibernate Reactive and Reactive PostgreSQL Client

Do you have a reproducer?

no yet

But can be reproduced by creating a Hibernate entity with a field like this:

    @Lob
    @Column(name = "data")
    public byte[] data;

And set the field to null, then it doesn't work. If you set it to an empty byte array it will work again.

Extra

Looks like this was introduced by this PR here #1464

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions