首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多线程jpa读取时Hibernate空指针异常

问多线程jpa读取时Hibernate空指针异常
EN

Stack Overflow用户
提问于 2021-01-10 04:39:23
回答 1查看 191关注 0票数 1

我有一个spring-batch作业,它使用RepositoryItemReader从数据库中读取数据,然后将结果转换为Map,然后将结果写入elasticsearch。它工作得很好,虽然有点慢。因此,现在我想添加一个池大小为4的taskExecutor,以提高速度:

代码语言:javascript
复制
        return stepBuilders.get("search-export").<AbstractEntityDefinition, Map<String, Object>>chunk(nemesisSearchProperties.getExport().getChunkSize())
                        .reader(reader)
                        .processor(processor)
                        .writer(writer)
                        .stream(reader)
                        .transactionAttribute(transactionAttribute)
                        .listener(chunkSessionReplicatorExecutionListener)
                        .listener(new NemesisChunkLoggingListener(indexName + " search export", nemesisSearchProperties.getExport().getChunkSize()))
                        .taskExecutor(searchExportTaskExecutor).throttleLimit(4) // <-- I add this
                        .build();

然而,在我添加任务执行器的那一刻,我得到了如下结果:

代码语言:javascript
复制
java.lang.NullPointerException
    at org.hibernate.internal.util.collections.IdentityMap.entryArray(IdentityMap.java:162)
    at org.hibernate.internal.util.collections.IdentityMap.concurrentEntries(IdentityMap.java:58)
    at org.hibernate.engine.internal.StatefulPersistenceContext.forEachCollectionEntry(StatefulPersistenceContext.java:1135)
    at org.hibernate.event.internal.AbstractFlushingEventListener.prepareCollectionFlushes(AbstractFlushingEventListener.java:193)
    at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:85)

看一下IdentityMap,我可以看到:

代码语言:javascript
复制
(1)     if ( entryArray == null ) {
(2)         entryArray = new Map.Entry[ map.size() ];
            final Iterator<Entry<IdentityKey<K>, V>> itr = map.entrySet().iterator();
            int i = 0;
            while ( itr.hasNext() ) {
                final Entry<IdentityKey<K>, V> me = itr.next();
(3)             entryArray[i++] = new IdentityMapEntry( me.getKey().key, me.getValue() ); // Here entryArray is NULL!!!
            }
        }

异常发生在第(3)行,其中entryArray为null。我想知道为什么会这样,因为在第(1)行检查entryArray为空,并在第(2)行将其初始化。

任何想法都将不胜感激。

EN

回答 1

Stack Overflow用户

发布于 2021-01-13 19:07:42

我不知道你的阅读器、处理器和编写器是什么样子的,但这看起来像是一个并发问题,因为跨线程共享Session。确保每个线程都有单独的会话。

请参阅文档:https://docs.spring.io/spring-batch/docs/current/reference/html/scalability.html

对于一些常见的批处理用例,使用多线程步骤实现有一些实际限制。步骤中的许多参与者(例如读取器和写入器)都是有状态的。如果状态不是由线程隔离的,那么这些组件在多线程步骤中是不可用的。特别是,来自Spring Batch的大多数现成的读取器和写入器都不是为多线程使用而设计的。

最好为所有对象创建一个包装器,这些对象在线程本地存储各自的读取器/写入器等。

Java/Jakarta Batch做到了这一点。读取器、写入器、处理器实例总是按分区计算的,因此您永远不会遇到问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65647375

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档