JPA单向一对多更新问题

Order和OrderItem有如下关系

Order.java

@OneToMany(cascade = { CascadeType.PERSIST, CascadeType.REFRESH,
      CascadeType.MERGE, CascadeType.REMOVE }, fetch = FetchType.EAGER,
      mappedBy = "order",orphanRemoval=true)
  private Set<OrderItem> 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。

如果是这么做: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,这个时候则正常更新数据库。

不解


你可能感兴趣的:(JPA单向一对多更新问题)