Java Jpa persist/merge在循环内抛出ConcurrentModificationException

Java Jpa persist/merge在循环内抛出ConcurrentModificationException,java,jpa,Java,Jpa,假设我有一个实体人,它存储属于那个人的汽车 @Entity @Table public class Person imlpements Serializable { @OneToMany(mappedBy = "person") private List<Car> cars = new ArrayList<Car>(); } @Entity @Table public class Car imlpements Serializable { @Man

假设我有一个实体人,它存储属于那个人的汽车

@Entity
@Table
public class Person imlpements Serializable
{
    @OneToMany(mappedBy = "person")
    private List<Car> cars = new ArrayList<Car>();
}

@Entity
@Table
public class Car imlpements Serializable
{
   @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
  @JoinColumn(name = "person_id")
    private Person person
}
编辑。这是我的实体经理:

@PersistenceContext(unitName = "DBService")
private EntityManager em;
这是堆栈跟踪

at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372) [:1.6.0_30]
at java.util.AbstractList$Itr.next(AbstractList.java:343) [:1.6.0_30]
at org.hibernate.collection.AbstractPersistentCollection$IteratorProxy.next(AbstractPersistentCollection.java:580) [:3.6.0.Final]
at com.importer Import.findCars(Import.java:114) [:]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [:1.6.0_30]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) [:1.6.0_30]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) [:1.6.0_30]
at java.lang.reflect.Method.invoke(Method.java:597) [:1.6.0_30]
at org.jboss.aop.joinpoint.MethodInvocation.invokeTarget(MethodInvocation.java:122) [jboss-aop.jar:2.2.1.GA]
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:111) [jboss-aop.jar:2.2.1.GA]
at org.jboss.ejb3.interceptors.container.ContainerMethodInvocationWrapper.invokeNext(ContainerMethodInvocationWrapper.java:72) [:1.1.3]
at org.jboss.ejb3.interceptors.aop.InterceptorSequencer.invoke(InterceptorSequencer.java:76) [:1.1.3]
at org.jboss.ejb3.interceptors.aop.InterceptorSequencer.aroundInvoke(InterceptorSequencer.java:62) [:1.1.3]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [:1.6.0_30]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) [:1.6.0_30]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) [:1.6.0_30]
at java.lang.reflect.Method.invoke(Method.java:597) [:1.6.0_30]
at org.jboss.aop.advice.PerJoinpointAdvice.invoke(PerJoinpointAdvice.java:174) [jboss-aop.jar:2.2.1.GA]
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) [jboss-aop.jar:2.2.1.GA]
at org.jboss.ejb3.interceptors.aop.InvocationContextInterceptor.fillMethod(InvocationContextInterceptor.java:74) [:1.1.3]
at org.jboss.aop.advice.org.jboss.ejb3.interceptors.aop.InvocationContextInterceptor_z_fillMethod_10768571.invoke(InvocationContextInterceptor_z_fillMethod_10768571.java) [:]
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) [jboss-aop.jar:2.2.1.GA]
at org.jboss.ejb3.interceptors.aop.InvocationContextInterceptor.setup(InvocationContextInterceptor.java:90) [:1.1.3]
at org.jboss.aop.advice.org.jboss.ejb3.interceptors.aop.InvocationContextInterceptor_z_setup_10768571.invoke(InvocationContextInterceptor_z_setup_10768571.java) [:]
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) [jboss-aop.jar:2.2.1.GA]
at org.jboss.ejb3.async.impl.interceptor.AsynchronousServerInterceptor.invoke(AsynchronousServerInterceptor.java:128) [:1.7.17]
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) [jboss-aop.jar:2.2.1.GA]
at org.jboss.ejb3.connectionmanager.CachedConnectionInterceptor.invoke(CachedConnectionInterceptor.java:62) [:1.7.17]
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) [jboss-aop.jar:2.2.1.GA]
at org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor.invoke(TransactionScopedEntityManagerInterceptor.java:56) [:1.7.17]
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) [jboss-aop.jar:2.2.1.GA]
at org.jboss.ejb3.concurrency.aop.interceptor.ContainerManagedConcurrencyInterceptor.invoke(ContainerManagedConcurrencyInterceptor.java:181) [:1.0.0-alpha-4]
at org.jboss.aop.advice.PerInstanceInterceptor.invoke(PerInstanceInterceptor.java:86) [jboss-aop.jar:2.2.1.GA]
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) [jboss-aop.jar:2.2.1.GA]
at org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInterceptor.java:47) [:1.7.17]
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) [jboss-aop.jar:2.2.1.GA]
at org.jboss.ejb3.tx.NullInterceptor.invoke(NullInterceptor.java:42) [:1.0.3]
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) [jboss-aop.jar:2.2.1.GA]
at org.jboss.ejb3.core.context.SessionInvocationContextAdapter.proceed(SessionInvocationContextAdapter.java:95) [:1.7.17]
at org.jboss.ejb3.tx2.impl.CMTTxInterceptor.invokeInOurTx(CMTTxInterceptor.java:247) [:0.0.1]
at org.jboss.ejb3.tx2.impl.CMTTxInterceptor.required(CMTTxInterceptor.java:349) [:0.0.1]
at org.jboss.ejb3.tx2.impl.CMTTxInterceptor.invoke(CMTTxInterceptor.java:209) [:0.0.1]
at org.jboss.ejb3.tx2.aop.CMTTxInterceptorWrapper.invoke(CMTTxInterceptorWrapper.java:52) [:0.0.1]
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) [jboss-aop.jar:2.2.1.GA]
at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:76) [:1.0.0.GA]
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) [jboss-aop.jar:2.2.1.GA]
at org.jboss.ejb3.tx.NullInterceptor.invoke(NullInterceptor.java:42) [:1.0.3]
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) [jboss-aop.jar:2.2.1.GA]
at org.jboss.ejb3.async.impl.interceptor.AsynchronousClientInterceptor.invoke(AsynchronousClientInterceptor.java:143) [:1.7.17]
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) [jboss-aop.jar:2.2.1.GA]
at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:41) [:1.7.17]
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) [jboss-aop.jar:2.2.1.GA]
at org.jboss.ejb3.BlockContainerShutdownInterceptor.invoke(BlockContainerShutdownInterceptor.java:67) [:1.7.17]
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) [jboss-aop.jar:2.2.1.GA]
at org.jboss.ejb3.core.context.CurrentInvocationContextInterceptor.invoke(CurrentInvocationContextInterceptor.java:47) [:1.7.17]
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) [jboss-aop.jar:2.2.1.GA]
at org.jboss.aspects.currentinvocation.CurrentInvocationInterceptor.invoke(CurrentInvocationInterceptor.java:67) [:1.0.1]
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) [jboss-aop.jar:2.2.1.GA]
at org.jboss.ejb3.interceptor.EJB3TCCLInterceptor.invoke(EJB3TCCLInterceptor.java:86) [:1.7.17]
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) [jboss-aop.jar:2.2.1.GA]
at org.jboss.ejb3.singleton.aop.impl.AOPBasedInterceptorRegistry.intercept(AOPBasedInterceptorRegistry.java:110) [:1.0.0-alpha-28]
at org.jboss.ejb3.singleton.impl.container.SingletonContainer.invoke(SingletonContainer.java:206) [:1.0.0-alpha-28]
at org.jboss.ejb3.singleton.aop.impl.AOPBasedSingletonContainer.dynamicInvoke(AOPBasedSingletonContainer.java:432) [:1.0.0-alpha-28]
at org.jboss.ejb3.session.InvokableContextClassProxyHack._dynamicInvoke(InvokableContextClassProxyHack.java:53) [:1.7.17]
at org.jboss.aop.Dispatcher.invoke(Dispatcher.java:91) [jboss-aop.jar:2.2.1.GA]
at org.jboss.aspects.remoting.AOPRemotingInvocationHandler.invoke(AOPRemotingInvocationHandler.java:82) [:1.0.1.GA]
at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:898) [:6.0.0.Final]
at org.jboss.remoting.transport.socket.ServerThread.completeInvocation(ServerThread.java:791) [:6.0.0.Final]
at org.jboss.remoting.transport.socket.ServerThread.processInvocation(ServerThread.java:744) [:6.0.0.Final]
at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:548) [:6.0.0.Final]
at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:234) [:6.0.0.Final]

在迭代该列表时,您似乎正在修改
Person.cars
列表。这是不允许的

我怀疑正在发生的是:

  • 您迭代
    Person.cars
    列表,并针对每个项目
  • 您可以持久化
    Car
    对象
  • Persist
    Car
    对象导致Hibernate需要更新
    Person.cars
    车主列表。该列表与您在步骤1中迭代的列表相同,因此您获得了
    ConcurrentModificationException
  • 您可以尝试执行以下操作的解决方案:

    CopyOnWriteArrayList<Car> personCars = 
        new CopyOnWriteArrayList<Car>( person.getCars() );
    
    for (Car c : personCars) em.merge(c);
    
    CopyOnWriteArrayList personCars=
    新的CopyOnWriteArrayList(person.getCars());
    对于(carc:personCars)em.merge(c);
    

    关于,

    在迭代该列表时,您似乎正在修改
    Person.cars
    列表。这是不允许的

    我怀疑正在发生的是:

  • 您迭代
    Person.cars
    列表,并针对每个项目
  • 您可以持久化
    Car
    对象
  • Persist
    Car
    对象导致Hibernate需要更新
    Person.cars
    车主列表。该列表与您在步骤1中迭代的列表相同,因此您获得了
    ConcurrentModificationException
  • 您可以尝试执行以下操作的解决方案:

    CopyOnWriteArrayList<Car> personCars = 
        new CopyOnWriteArrayList<Car>( person.getCars() );
    
    for (Car c : personCars) em.merge(c);
    
    CopyOnWriteArrayList personCars=
    新的CopyOnWriteArrayList(person.getCars());
    对于(carc:personCars)em.merge(c);
    

    关于,

    请发布实际异常+堆栈跟踪。你确定你应该使用合并吗?我假设您正在更改的汽车是托管实体,因此与数据库的同步由JPA持久性提供程序处理。可以肯定的是,您的“em”变量是什么?一辆汽车可以属于多个人吗?因为在这种情况下,一个car实例应该在同一个会话中提交两次…@Neron。不,一辆车只属于一个人Person@Gimby. 我正在使用合并。因为汽车可以是新创建的(不是管理的),也可以是已管理的。请将实际的异常+stacktrace放在前面。你确定你应该使用合并吗?我假设您正在更改的汽车是托管实体,因此与数据库的同步由JPA持久性提供程序处理。可以肯定的是,您的“em”变量是什么?一辆汽车可以属于多个人吗?因为在这种情况下,一个car实例应该在同一个会话中提交两次…@Neron。不,一辆车只属于一个人Person@Gimby. 我正在使用合并。因为汽车可以是新创建的(不是管理的),也可以已经是经理了