The code of my Spring Data repository method is as follows:
public Optional<byte[]> findShipmentLabelByClientIdAndAwb(String clientId, String awb) {
String queryString = "select g.shipmentLabel as shipmentLabel from GenericShipment g where g.client.id = :clientId and g.shipmentId = :awb " +
" AND (g.processingStatus is null or g.processingStatus <> 'DELETED') AND g.shipmentLabel is not null";
val query = entityManager.createQuery(queryString, byte[].class);
query.setParameter("clientId", clientId);
query.setParameter("awb", awb);
return query.getResultStream().findFirst();
}
As you can see, I am attempting to fetch, as byte array, the shipmentLabel column, defined in my Postgres schema as bytea. The following exception occurs at runtime:
java.lang.ClassCastException: [B cannot be cast to [Ljava.lang.Object; at org.hibernate.internal.ScrollableResultsImpl.prepareCurrentRow(ScrollableResultsImpl.java:203) at org.hibernate.internal.ScrollableResultsImpl.next(ScrollableResultsImpl.java:101) at org.hibernate.query.internal.ScrollableResultsIterator.hasNext(ScrollableResultsIterator.java:33) at java.util.Spliterators$IteratorSpliterator.tryAdvance(Spliterators.java:1811) at java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:126) at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:499) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:486) at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472) at java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:152) at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:531) at org.hibernate.query.spi.StreamDecorator.findFirst(StreamDecorator.java:260)
I was wondering if this is the intended behaviour here or not, thanks in advance for your answers.
For the time being, the workaround is to use the JPA 2.1 variant:
return query.getResultList().stream().findFirst();
As environment, I am using Spring Boot 2.3.3, Hibernate version is 5.4.20.
Try with
getResultList
first, and see if it works:Note that it's inefficient to select N records only to take the first one using
fidFirst
. What if this query returns 100 records? You'd still select all 100 from the DB.That's why I added the
setMaxResults
call.If that doesn't work, try debugging the Hibernate
BinaryType
and see why it doesn't returnbyte[]
.