使用带有DozerMaper的parallelStream映射对象列表会产生StackOverflowError

时间:2016-02-09 14:51:46

标签: java dozer

我有以下实用程序方法将域对象的List映射到DTO,从而生成映射对象的列表。

 public static <Z, T> List<T> mapList(Mapper mapper, List<Z> source, Class<T> type) {
     return source.parallelStream()
             .map((s) -> mapper.map(s, type))
             .collect(Collectors.toList());
}

作为映射器,我传递DozerBeanMaper的单例实例(由Spring管理的实例)。 List源是hibernate查询的结果。上面的代码工作正常。

现在,我已经更改代码以使用Stream API(我希望并行化映射):

Caused by: java.lang.NullPointerException
    at org.hibernate.engine.internal.StatefulPersistenceContext.getLoadedCollectionOwnerOrNull(StatefulPersistenceContext.java:755)
    at org.hibernate.event.spi.AbstractCollectionEvent.getLoadedOwnerOrNull(AbstractCollectionEvent.java:75)
    at org.hibernate.event.spi.InitializeCollectionEvent.<init>(InitializeCollectionEvent.java:36)
    at org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:1895)
    at org.hibernate.collection.internal.AbstractPersistentCollection$4.doWork(AbstractPersistentCollection.java:558)
    at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:260)
    at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:554)
    at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:142)
    at org.hibernate.collection.internal.PersistentSet.iterator(PersistentSet.java:180)
    at org.dozer.MappingProcessor.addOrUpdateToList(MappingProcessor.java:766)
    at org.dozer.MappingProcessor.addOrUpdateToList(MappingProcessor.java:850)
    at org.dozer.MappingProcessor.mapListToList(MappingProcessor.java:686)
    at org.dozer.MappingProcessor.mapCollection(MappingProcessor.java:553)
    at org.dozer.MappingProcessor.mapOrRecurseObject(MappingProcessor.java:434)
    at org.dozer.MappingProcessor.mapFromFieldMap(MappingProcessor.java:342)
    at org.dozer.MappingProcessor.mapField(MappingProcessor.java:288)
    at org.dozer.MappingProcessor.map(MappingProcessor.java:248)
    at org.dozer.MappingProcessor.map(MappingProcessor.java:197)
    at org.dozer.MappingProcessor.mapCustomObject(MappingProcessor.java:495)
    at org.dozer.MappingProcessor.mapOrRecurseObject(MappingProcessor.java:446)
    at org.dozer.MappingProcessor.mapFromFieldMap(MappingProcessor.java:342)
    at org.dozer.MappingProcessor.mapField(MappingProcessor.java:288)
    at org.dozer.MappingProcessor.map(MappingProcessor.java:248)
    at org.dozer.MappingProcessor.map(MappingProcessor.java:197)
    at org.dozer.MappingProcessor.map(MappingProcessor.java:187)
    at org.dozer.MappingProcessor.map(MappingProcessor.java:124)
    at org.dozer.MappingProcessor.map(MappingProcessor.java:119)
    at org.dozer.DozerBeanMapper.map(DozerBeanMapper.java:120)
    at 
org.mycompany.myproject.utils.BeanMapperUtil.lambda$0(BeanMapperUtil.java:30)

并获得以下内容:

source.stream()

execption重复自身,最后变成StackOverFlowErorr。

如果我使用source.parallelStream()代替gwmi Win32_Process,我就不会收到任何错误。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

问题是该方法是在spring @Transactional注释方法中与延迟加载一起调用的。参见例如这篇文章] 1