gpt4 book ai didi

克隆实体上的 java.util.ConcurrentModificationException

转载 作者:行者123 更新时间:2023-11-30 08:08:31 25 4
gpt4 key购买 nike

我编写了一个自定义策略,以便克隆一个实体 TrainTimetable 及其槽位 集合。

下面是模型的摘录:

Entity('TrainTimetable') {
list 'slots' , ref:'Slot', composition:true
}
Entity('Slot') {
reference 'trainTimetable' , ref:'TrainTimetable', reverse:'TrainTimetable-slots'
}

方法如下:

package fr.yc.rail.backend;

import java.util.ArrayList;
import java.util.List;

import org.jspresso.framework.model.entity.IEntity;
import org.jspresso.framework.model.entity.IEntityFactory;
import org.jspresso.framework.model.entity.SmartEntityCloneFactory;

import fr.yc.rail.model.Slot;
import fr.yc.rail.model.TrainTimetable;

public class CloneTrainTimetableFactory extends SmartEntityCloneFactory {

@Override
public <E extends IEntity> E cloneEntity(E entityToClone,
IEntityFactory entityFactory) {

TrainTimetable clonedTrainTimetable = (TrainTimetable) super.cloneEntity(entityToClone, entityFactory);

TrainTimetable trainTimetableToClone = (TrainTimetable) entityToClone;

List<Slot> clonedSlots = new ArrayList<Slot>();

trainTimetableToClone.getSlots().each {
Slot clonedSlot = super.cloneEntity(it, entityFactory);
clonedSlots.add(clonedSlot);
}

clonedTrainTimetable.setSlots(clonedSlots);

return (E) clonedTrainTimetable;
}
}

调用该方法时,下面的代码在第二次迭代时引发 ConcurrentModificationException 错误:

trainTimetableToClone.getSlots().each {
Slot clonedSlot = super.cloneEntity(it, entityFactory);
clonedSlots.add(clonedSlot);
}

在堆栈跟踪下方:

ERROR <2015-06-09 18:13:11,193> org.jspresso.framework.application.frontend.controller.AbstractFrontendController : An unexpected error occurred for user demo on session 4379dc1b.
java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at org.hibernate.collection.internal.AbstractPersistentCollection$IteratorProxy.next(AbstractPersistentCollection.java:774)
at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:1378)
at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:1372)
at org.codehaus.groovy.runtime.dgm$149.invoke(Unknown Source)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:271)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:53)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at fr.yc.rail.backend.CloneTrainTimetableFactory.cloneEntity(CloneTrainTimetableFactory.groovy:25)
at org.jspresso.framework.application.backend.action.CloneComponentCollectionAction.cloneElement(CloneComponentCollectionAction.java:61)
at org.jspresso.framework.application.backend.action.AbstractCloneCollectionAction.getAddedComponents(AbstractCloneCollectionAction.java:71)
at org.jspresso.framework.application.backend.action.AbstractAddCollectionToMasterAction.execute(AbstractAddCollectionToMasterAction.java:78)
at org.jspresso.framework.application.backend.AbstractBackendController.execute(AbstractBackendController.java:403)
at org.jspresso.framework.application.frontend.controller.AbstractFrontendController.executeBackend(AbstractFrontendController.java:1536)
at org.jspresso.framework.application.frontend.controller.AbstractFrontendController.execute(AbstractFrontendController.java:576)
at org.jspresso.framework.application.action.AbstractAction.execute(AbstractAction.java:114)
at org.jspresso.framework.application.frontend.controller.AbstractFrontendController.executeFrontend(AbstractFrontendController.java:1549)
at org.jspresso.framework.application.frontend.controller.AbstractFrontendController.execute(AbstractFrontendController.java:578)
at org.jspresso.framework.view.remote.RemoteActionFactory$ActionAdapter.actionPerformed(RemoteActionFactory.java:235)
at org.jspresso.framework.application.frontend.controller.remote.AbstractRemoteController.handleCommand(AbstractRemoteController.java:440)
at org.jspresso.framework.application.frontend.controller.remote.AbstractRemoteController.handleCommands(AbstractRemoteController.java:202)
at org.jspresso.framework.application.startup.remote.RemoteStartup.handleCommands(RemoteStartup.java:88)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at net.sf.qooxdoo.rpc.RemoteCallUtils.callCompatibleMethod(RemoteCallUtils.java:469)
at net.sf.qooxdoo.rpc.RpcServlet.handleRPC(RpcServlet.java:374)
at net.sf.qooxdoo.rpc.RpcServlet.doPost(RpcServlet.java:481)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.jspresso.framework.util.http.HttpRequestHolder.doFilter(HttpRequestHolder.java:99)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:503)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)

该错误意味着我正在迭代一个大小正在变化的集合,但我不知道如何摆脱它。

最佳答案

TrainTimetableSlot 之间存在 1-N 双向关联。这意味着每当您更新关联的一侧时,Jspresso 将负责更新另一侧以保持模型一致性,例如:

  • 如果您在某个时段设置 trainTimetable 属性,该时段将被添加到火车时刻表的反向 slots 集合中。
  • 如果您向列车时刻表的 slots 属性添加一个时段,则添加时段的 trainTimetable 反向属性将更新为列车时刻表。<

在以下代码中:

 Slot clonedSlot = super.cloneEntity(it, entityFactory);

由于前面解释的规则,clonedSlot 将被添加到 trainTimeTableToClone 槽中。所以迭代后的集合实际上发生了变化。

为了解决这个问题,在迭代之前制作集合的副本就足够了,即:

trainTimetableToClone.getSlots().collect().each {

关于克隆实体上的 java.util.ConcurrentModificationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30737812/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com