JPAワンツールチアップデートの問題
5528 ワード
OrderとOrderItemには次のような関係があります.
Order.java
@OneToMany(cascade = { CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE, CascadeType.REMOVE }, fetch = FetchType.EAGER, mappedBy = "order",orphanRemoval=true) private Set orderItemList= new HashSet<>();
OrderItem.java
@ManyToOne(cascade = { CascadeType.MERGE, CascadeType.REFRESH }, optional = false) @JoinColumn(name = "order_id") private Order order;
ページに入ってくるのはOrder DTOで、中にはidとversionが入っています.
OrderServiceレイヤでは、orderIDに基づいてデータベース内のdbOrderが検出され、dbOrderItemListが取得されます.
問題は次のとおりです.
dbOrderが存在する場合は、データベース内のdbOrderItemListをページ転送のonlineOrderに割り当てる必要があります.
もしそうならsetOrderItemList(dbOrderItemList)では、onlineOrderを保存中に次のエラーが発生します.
ただし、dbOrderItemをループ設定すると、
for(OrderItem item: dbOrderItemList){
onlineOrder.addOrderItem(item);
}
その後、onlineOrderを保存します.この場合、データベースは正常に更新されます.
理解できない
Order.java
@OneToMany(cascade = { CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE, CascadeType.REMOVE }, fetch = FetchType.EAGER, mappedBy = "order",orphanRemoval=true) private Set
OrderItem.java
@ManyToOne(cascade = { CascadeType.MERGE, CascadeType.REFRESH }, optional = false) @JoinColumn(name = "order_id") private Order order;
ページに入ってくるのはOrder DTOで、中にはidとversionが入っています.
OrderServiceレイヤでは、orderIDに基づいてデータベース内のdbOrderが検出され、dbOrderItemListが取得されます.
問題は次のとおりです.
dbOrderが存在する場合は、データベース内のdbOrderItemListをページ転送のonlineOrderに割り当てる必要があります.
もしそうならsetOrderItemList(dbOrderItemList)では、onlineOrderを保存中に次のエラーが発生します.
java.util.ConcurrentModificationException
java.util.HashMap$HashIterator.nextEntry(HashMap.java:926)
java.util.HashMap$KeyIterator.next(HashMap.java:960)
org.hibernate.collection.internal.AbstractPersistentCollection$IteratorProxy.next(AbstractPersistentCollection.java:789)
org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:379)
org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:319)
org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:296)
org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161)
org.hibernate.engine.internal.Cascade.cascade(Cascade.java:118)
org.hibernate.event.internal.DefaultMergeEventListener.cascadeOnMerge(DefaultMergeEventListener.java:474)
org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:343)
org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:186)
org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:85)
org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:876)
org.hibernate.internal.SessionImpl.merge(SessionImpl.java:858)
org.hibernate.internal.SessionImpl.merge(SessionImpl.java:863)
org.hibernate.jpa.spi.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:1196)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:606)
org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:342)
com.sun.proxy.$Proxy69.merge(Unknown Source)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:606)
org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:289)
com.sun.proxy.$Proxy69.merge(Unknown Source)
org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:396)
org.springframework.data.jpa.repository.support.SimpleJpaRepository.saveAndFlush(SimpleJpaRepository.java:407)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:606)
org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:442)
org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:427)
org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:381)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:266)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodIntercceptor.invoke(CrudMethodMetadataPostProcessor.java:111)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
ただし、dbOrderItemをループ設定すると、
for(OrderItem item: dbOrderItemList){
onlineOrder.addOrderItem(item);
}
その後、onlineOrderを保存します.この場合、データベースは正常に更新されます.
理解できない