java.lang.ClassCastException : [B cannot be cast to [Ljava. lang.Object;使用 JPA 2.2 query.getResultStream().findFirst() 时

标签 java spring-data-jpa hibernate-5.x jpa-2.2

我的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();

}

如您所见,我正在尝试以字节数组的形式获取 shipmentLabel 列,该列在我的 Postgres 架构中定义为 bytea。 运行时出现如下异常:

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)

我想知道这是否是这里的预期行为,提前感谢您的回答。

目前,解决方法是使用 JPA 2.1 变体:

return query.getResultList().stream().findFirst();

作为环境,我使用的是Spring Boot 2.3.3Hibernate版本是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[]

关于java.lang.ClassCastException : [B cannot be cast to [Ljava. lang.Object;使用 JPA 2.2 query.getResultStream().findFirst() 时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64059595/

相关文章:

java - 具有可变参数列表的方法

java - 为什么 STS 会警告我参数不匹配?

java - JPA 与 Hibernate 5 : programmatically create EntityManagerFactory

java - 异常线程 "main"java.lang.IllegalArgumentException : org. hibernate.hql.internal.ast.QuerySyntaxException 得到这个 Excdption

Java 键盘获取移位字符

java - NoClassDefFoundError : org/apache/poi/ss/formula/udf/UDFFinder error in java

java - spring data,PagingAndSorting存储库,根据类类型的(嵌套)属性值进行排序

mysql - Hibernate 5.0.12找不到MySQL列

java - 获取所有挂起的请求一对多映射

java - 将对象的防御性副本添加到哈希集中