Java 如何解决更新子元素时的ConcurrentModificationException?

Java 如何解决更新子元素时的ConcurrentModificationException?,java,exception,concurrentmodification,Java,Exception,Concurrentmodification,我有一个合同实体,其属性指定为: @OneToMany(fetch = FetchType.EAGER, mappedBy = "contract") @Fetch(FetchMode.SELECT) private List<ContractDetail> details; 这里的想法是,每当创建一个ContractCoverParameter实体时,通过调用下面转录的UpdateContactDetailList()方法,为所有Contract创建一个ContractDetai

我有一个
合同
实体,其属性指定为:

@OneToMany(fetch = FetchType.EAGER, mappedBy = "contract")
@Fetch(FetchMode.SELECT)
private List<ContractDetail> details;
这里的想法是,每当创建一个
ContractCoverParameter
实体时,通过调用下面转录的
UpdateContactDetailList()
方法,为所有
Contract
创建一个
ContractDetail

public void updateContractDetailList() {
    List<ContractDetail> details = new ArrayList<ContractDetail>();

    for (Contract contract : contractService.findAll()) {

        details = contract.getDetails();

        if (contract.getDetails() != null || contract.getDetails().size() != 0) {

            for (ContractCoverParameter coverParameter : findAll()) {

                ContractDetail cDetail = new ContractDetail();
                cDetail.setContract(contract);
                cDetail.setCoverParameter(coverParameter);
                cDetail.setValue("");

                cDetail = contractDetailService.saveContractDetail(cDetail);

                details.add(cDetail);
                contract.setDetails(details);
            }
            contractService.updateContract(contract);
        }
    }
}
而且,
contractService.updateContract(Contract Contract)
调用以下方法:

protected T persistT(T entity) {
    getSession().persist(entity);
    flush();
    return entity;
}
public void saveOrUpdate(T entity) {
    try {
        clear();
        getSession().saveOrUpdate(entity);
        flush();
        getSession().beginTransaction().commit();
        getSession().close();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (getSession().getTransaction() == null) {
            rollback();
        }
    }
}
根据要求编辑评论:

public List<T> findAll() {
    return getSession().createCriteria(persistentClass).list();
}

这里发生了什么以及如何解决这个问题?

尝试将
findAll()
移动到循环之外

public void updateContractDetailList() {
    List<ContractDetail> details = new ArrayList<ContractDetail>();
    List<Contract> contracts = contractService.findAll();
    List<ContractCoverParameter> contractCoverParams = findAll();

    for (Contract contract : contracts) {

        details = contract.getDetails();

        if (contract.getDetails() != null || contract.getDetails().size() != 0) {

            for (ContractCoverParameter coverParameter : contractCoverParams) {

                ContractDetail cDetail = new ContractDetail();
                cDetail.setContract(contract);
                cDetail.setCoverParameter(coverParameter);
                cDetail.setValue("");

                cDetail = contractDetailService.saveContractDetail(cDetail);

                details.add(cDetail);
                contract.setDetails(details);
            }
            contractService.updateContract(contract);
        }
    }
}
public void updateContactDetailList(){
列表详细信息=新建ArrayList();
List contracts=contractService.findAll();
List contractCoverParams=findAll();
用于(合同:合同){
details=contract.getDetails();
if(contract.getDetails()!=null | | contract.getDetails().size()!=0){
对于(ContractCoverParameter coverParameter:contractCoverParams){
ContractDetail cDetail=新的ContractDetail();
cDetail.setContract(合同);
cDetail.setCoverParameter(coverParameter);
cDetail.setValue(“”);
cDetail=contractDetailService.saveContractDetail(cDetail);
详细信息。添加(cDetail);
合同详情(详情);
}
contractService.UpdateContact(合同);
}
}
}

尝试将
findAll()移出循环

public void updateContractDetailList() {
    List<ContractDetail> details = new ArrayList<ContractDetail>();
    List<Contract> contracts = contractService.findAll();
    List<ContractCoverParameter> contractCoverParams = findAll();

    for (Contract contract : contracts) {

        details = contract.getDetails();

        if (contract.getDetails() != null || contract.getDetails().size() != 0) {

            for (ContractCoverParameter coverParameter : contractCoverParams) {

                ContractDetail cDetail = new ContractDetail();
                cDetail.setContract(contract);
                cDetail.setCoverParameter(coverParameter);
                cDetail.setValue("");

                cDetail = contractDetailService.saveContractDetail(cDetail);

                details.add(cDetail);
                contract.setDetails(details);
            }
            contractService.updateContract(contract);
        }
    }
}
public void updateContactDetailList(){
列表详细信息=新建ArrayList();
List contracts=contractService.findAll();
List contractCoverParams=findAll();
用于(合同:合同){
details=contract.getDetails();
if(contract.getDetails()!=null | | contract.getDetails().size()!=0){
对于(ContractCoverParameter coverParameter:contractCoverParams){
ContractDetail cDetail=新的ContractDetail();
cDetail.setContract(合同);
cDetail.setCoverParameter(coverParameter);
cDetail.setValue(“”);
cDetail=contractDetailService.saveContractDetail(cDetail);
详细信息。添加(cDetail);
合同详情(详情);
}
contractService.UpdateContact(合同);
}
}
}

请在源代码中标记
br.com.mentium.hrm.service.impl.ContractCoverParameterServiceImpl.UpdateContactDetailList(ContractCoverParameterServiceImpl.java:128)
。提供
findAll()
code.
UpdateContact‌​DetailList()
是问题中显示的方法已经提供了findAll()`这个错误背后的一般思想是“在使用时不要更改”,在特定情况下使用通常意味着迭代。在这种情况下,我想说由
#findAll
提供的迭代器不可避免地使用了由
#updateContract
修改的集合,该集合位于
ContractCoverParameterServiceImpl.java:128
?请标记
br.com.mentium.hrm.service.impl.ContractCoverParameterServiceImpl.updateContractDetailList(ContractCoverParameterServiceImpl.java:128)
在源代码中。提供
findAll()‌​DetailList()
是问题中显示的方法。已提供了'findAll()'。错误背后的一般思想是“在使用时不要更改”,在特定情况下使用通常意味着迭代。在这种情况下,我要说,从
#findAll
提供的迭代器不可避免地使用了一个由
#updateContract
修改的集合,该集合位于
ContractCoverParameterServiceImpl.java:128
?谢谢,伙计!它已经工作了。唯一缺少这一点的是不完美的我得到了一个
org.hibernate.TransactionException:不支持嵌套事务
。这种情况已经发生了一段时间了,我还没有弄明白。谢谢,伙计!它已经起作用了。唯一不完美的是,我现在得到了
org.hibernate.TransactionException:不支持嵌套事务
.这件事已经发生了一段时间了,我还没弄明白。
public void updateContractDetailList() {
    List<ContractDetail> details = new ArrayList<ContractDetail>();
    List<Contract> contracts = contractService.findAll();
    List<ContractCoverParameter> contractCoverParams = findAll();

    for (Contract contract : contracts) {

        details = contract.getDetails();

        if (contract.getDetails() != null || contract.getDetails().size() != 0) {

            for (ContractCoverParameter coverParameter : contractCoverParams) {

                ContractDetail cDetail = new ContractDetail();
                cDetail.setContract(contract);
                cDetail.setCoverParameter(coverParameter);
                cDetail.setValue("");

                cDetail = contractDetailService.saveContractDetail(cDetail);

                details.add(cDetail);
                contract.setDetails(details);
            }
            contractService.updateContract(contract);
        }
    }
}