首页 > 解决方案 > 将 Java 流与 ORMLite 一起使用

问题描述

我最近决定将我的应用程序(一个相当简单的 RESTful API 套件)切换为对许多资源端点使用 Java Streams,例如:

@ForeignCollectionField
protected ForeignCollection<>   people;
@GET
public Set<Person> getStaff() {
        return people.stream()
                .filter(n -> (n.role & Person.ROLE_STAFF) == Person.ROLE_STAFF)
                .map(n -> n.left)
                .collect(Collectors.toSet());
}

在这种情况下——以及其他大多数情况下——人们是一个懒惰的人ForeignCollection

但是,这导致出现大量并发请求的各种错误:

java.lang.ArrayIndexOutOfBoundsException
        at java.lang.System.arraycopy(Native Method)
        at org.mariadb.jdbc.internal.com.read.Buffer.getLengthEncodedBytes(Buffer.java:318)
        at org.mariadb.jdbc.internal.com.read.resultset.ColumnInformation.getString(ColumnInformation.java:235)
        at org.mariadb.jdbc.internal.com.read.resultset.ColumnInformation.getName(ColumnInformation.java:251)
        at org.mariadb.jdbc.internal.com.read.dao.ColumnNameMap.getIndex(ColumnNameMap.java:90)
        at org.mariadb.jdbc.internal.com.read.resultset.SelectResultSet.findColumn(SelectResultSet.java:1368)
        at com.j256.ormlite.jdbc.JdbcDatabaseResults.findColumn(JdbcDatabaseResults.java:103)
        at com.j256.ormlite.field.FieldType.resultToJava(FieldType.java:826)
        at com.j256.ormlite.stmt.mapped.BaseMappedQuery.mapRow(BaseMappedQuery.java:44)
        at com.j256.ormlite.stmt.SelectIterator.getCurrent(SelectIterator.java:297)
        at com.j256.ormlite.stmt.SelectIterator.nextThrow(SelectIterator.java:168)
        at com.j256.ormlite.stmt.SelectIterator.next(SelectIterator.java:181)
        at java.util.Iterator.forEachRemaining(Iterator.java:116)
        at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
        at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
        at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
        at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
        at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
        at java.util.stream.LongPipeline.reduce(LongPipeline.java:438)
        at java.util.stream.LongPipeline.sum(LongPipeline.java:396)
        at java.util.stream.ReferencePipeline.count(ReferencePipeline.java:526)

我使用 Jersey 作为框架,一些 API 调用使用@ManagedAsync,一些不使用。没有@Singletons。Dao对象是共享的,并且存在 LRU 缓存(所有 Dao 对象之间共享)

我的问题:为什么我会收到这些奇怪的错误?nORMlite 是否支持使用 Streams?如果是这样,我如何确保安全?

我试过这个:

try (final CloseableWrappedIterable<PeopleToClub> p = people.getWrappedIterable()) {
  if (asStream(p.iterator()).filter(n -> n.left.getId() == user.getPerson().getId()
    && n.role == Person.ROLE_STAFF).count() > 0) {
    return true;
  }
  return false;
} catch (final IOException e) {
  return false;
}

然而,“随机”错误仍然存​​在。

持久层是MariaDB,所以并发访问应该没有问题(另外,它只是SELECT)

标签: javajerseyormlite

解决方案


推荐阅读