Issue
I'am setting up a simple Quarkus application using hibernate for testing Quarkus capabilities. It contains a simple hibernate mapping
@Entity
Class AnEntity{
public double[] data;
}
It maps to the postgresql table anentity(data bytea). This is fine for me and works well when running on JVM: zero problem on this side. I can read easily the content of the table using a NativeQuery.
Query query = em.createNativeQuery("select * from anentity",AnEntity.class);
List<AnEntity> resultList = query.getResultList();
for (AnEntity anEntity: resultList) {
System.out.println(anEntity.data);
}
The behavior here is that the content of the data array is serialized/deserialized using "standard" java serialization when reading/writing the data field from and to the database.
Now when compiling in native mode, I have a serialization related exception that follows:
ERROR [io.qua.run.Application] (main) Failed to start application (with profile prod): java.io.StreamCorruptedException: invalid type code: 40
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1712)
at java.io.ObjectInputStream.readArray(ObjectInputStream.java:2103)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1669)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:493)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:451)
at org.hibernate.internal.util.SerializationHelper.doDeserialize(SerializationHelper.java:225)
at org.hibernate.internal.util.SerializationHelper.deserialize(SerializationHelper.java:287)
at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.fromBytes(SerializableTypeDescriptor.java:138)
at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.wrap(SerializableTypeDescriptor.java:113)
at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.wrap(SerializableTypeDescriptor.java:29)
at org.hibernate.type.descriptor.sql.VarbinaryTypeDescriptor$2.doExtract(VarbinaryTypeDescriptor.java:60)
at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:47)
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.loader.Loader.loadFromResultSet(Loader.java:1887)
at org.hibernate.loader.Loader.hydrateEntityState(Loader.java:1811)
at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1784)
at org.hibernate.loader.Loader.getRow(Loader.java:1624)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:748)
at org.hibernate.loader.Loader.getRowsFromResultSet(Loader.java:1047)
I tried to register double[].class in a @RegisterForReflection annotation, changing double[] to Double[] but it did not help.
I'am not sure what's wrong here. It looks like the Java default serialization/deserialization is not working well in native mode, and I'am wondering how to solve this.
Thanks for any hints/pointer. I have the feeling it is a simple problem of a missing declaration or configuration parameter somewhere, at least I hope so :) I'll double check known issues with Java deserialization in native mode.
Solution
Solved! After more investigations it was a simple matter of registering the double[] class in native image builder serialization configuration file.
Added this line in the quarkus application.properties:
quarkus.native.additional-build-args = -H:SerializationConfigurationResources=serialization-config.json
and serialization-config.json being simply
[
{"name":"double[]"}
]
Answered By - greg
Answer Checked By - Terry (JavaFixing Volunteer)