![](/img/trans.png)
[英]java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to
[英]java.lang.ClassCastException: [B cannot be cast to [Ljava.lang.Object; while using JPA 2.2 query.getResultStream().findFirst()
我的 Spring Data 存儲庫方法的代碼如下:
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();
}
如您所見,我正在嘗試以字節數組的形式獲取在 Postgres 架構中定義為bytea的shipmentLabel列。 運行時出現以下異常:
java.lang.ClassCastException: [B 不能轉換為 [Ljava.lang.Object ; 在 org.hibernate.internal.ScrollableResultsImpl.prepareCurrentRow(ScrollableResultsImpl.java:203) 在 org.hibernate.internal.ScrollableResultsImpl.next(ScrollableResultsImpl.java:101) 在 org.hibernate.query.internal.ScrollableResultsIterator.haseratorNext(ScrollableResultsIterator.haseratorNext(ScrollableResultsIterator) :33) 在 java.util.Spliterators$IteratorSpliterator.tryAdvance(Spliterators.java:1811) 在 java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:126) 在 java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline. java:499) 在 java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:486) 在 java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472) 在 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)
我想知道這是否是這里的預期行為,在此先感謝您的回答。
目前,解決方法是使用 JPA 2.1 變體:
返回 query.getResultList().stream().findFirst();
作為環境,我使用的是Spring Boot 2.3.3 , Hibernate版本是5.4.20 。
首先嘗試使用getResultList
,看看它是否有效:
public Optional<Byte[]> findShipmentLabelByClientIdAndAwb(
String clientId, String awb) {
return entityManager.createQuery("""
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
""")
.setParameter("clientId", clientId)
.setParameter("awb", awb)
.setMaxResults(1)
.getResultList()
.stream()
.findFirst();
}
請注意,使用fidFirst
僅選擇 N 條記錄以獲取第一條記錄是低效的。 如果此查詢返回 100 條記錄怎么辦? 您仍然會從數據庫中選擇所有 100 個。
這就是我添加setMaxResults
調用的原因。
如果這不起作用,請嘗試調試 Hibernate BinaryType
並查看它為什么不返回byte[]
。
字節沒有原始流,您可以在調試器中檢查您獲得的流的類型,可能是Stream<Byte[]>
或Stream<Object[]>
。 這可以解釋您得到的異常。 使用 Byte[] 應該可以解決您的問題。
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();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.