Java8 Stream을 사용하다 보면 자주 발생할 수 있는 미묘한 실수 중에 하나는
이미 사용했던 Stream을 다시 사용하려고 하는 것이다. Stream은 오직 한 번만 사용할 수 있다.
A Stream should be operated on (invoking an intermediate or terminal stream operation) only once.
A Stream implementation may throw IllegalStateException if it detects that the Stream is being reused.
이미 사용했던 Stream을 또 사용하게 될 경우 다음과 같은 에러 로그를 발견할 수 있을 것이다.
java.lang.IllegalStateException: stream has already been operated upon or closed
at java.util.stream.AbstractPipeline.sourceStageSpliterator(AbstractPipeline.java:279)
at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
at com.payco.cm.service.CacheService.cachingPartnerUrlMap(CacheService.java:31)
at com.payco.cm.service.CacheService$$FastClassBySpringCGLIB$$d06ada09.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.cache.interceptor.CacheInterceptor$1.invoke(CacheInterceptor.java:52)
at org.springframework.cache.interceptor.CacheAspectSupport.invokeOperation(CacheAspectSupport.java:344)
at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:407)
at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:326)
at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:61)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
[ 문제가 발생했던 코드 ]
코드를 보면 Stream을 두 번 사용하고 있는 것을 볼 수있다.
로깅기능으로 잠깐 보려고 했던 코드가 문제가 되었다.
정리하자면
Stream shoud be used only Once!!!