Java 在Hibernate中保存大型集合时发生ConcurrentModificationException

Java 在Hibernate中保存大型集合时发生ConcurrentModificationException,java,multithreading,hibernate,Java,Multithreading,Hibernate,我有以下问题: 我有一个应用程序,当一个实体应该保存在数据库中时,它将一个DatabaseJob发送到一个单独线程中的队列。当队列有作业时,此工作线程从队列中获取第一个作业并使用Hibernate保存它。总的来说,这很好用 我遇到的问题出现在尝试保存大型集合(1000多个)条目时。当Hibernate尝试将集合刷新到数据库时,可能会修改集合,从而导致以下ConcurrentModificationException 2014-09-01 10:37:57,301 ERROR [DatabaseM

我有以下问题:

我有一个应用程序,当一个实体应该保存在数据库中时,它将一个DatabaseJob发送到一个单独线程中的队列。当队列有作业时,此工作线程从队列中获取第一个作业并使用Hibernate保存它。总的来说,这很好用

我遇到的问题出现在尝试保存大型集合(1000多个)条目时。当Hibernate尝试将集合刷新到数据库时,可能会修改集合,从而导致以下
ConcurrentModificationException

2014-09-01 10:37:57,301 ERROR [DatabaseManager] [Thread: database-message-queue] Hibernate - Unhandled Exception during saving
java.util.ConcurrentModificationException
    at java.util.LinkedHashMap$LinkedHashIterator.nextNode(LinkedHashMap.java:711)
    at java.util.LinkedHashMap$LinkedKeyIterator.next(LinkedHashMap.java:734)
    at org.hibernate.collection.internal.PersistentSet.getSnapshot(PersistentSet.java:96)
    at org.hibernate.engine.spi.CollectionEntry.afterAction(CollectionEntry.java:246)
    at org.hibernate.action.internal.CollectionUpdateAction.execute(CollectionUpdateAction.java:105)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:463)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:349)
    at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:350)
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:56)
    at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1222)
    at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:425)
    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:177)
通过使用
collections.synchronizexx
,我使用的所有集合对于并发访问都是安全的,但对于迭代,它必须手动同步

有没有办法通过Hibernate分别使用线程安全迭代器同步集合访问?我已经尝试过使用
org.hibernate.usertype.UserCollectionType
,但也没有成功

否则,我认为在将实体添加到数据库队列之前,可能必须复制它们,但我希望有一种更简单的方法

提前非常感谢, 本杰明·高尼茨

更新1->相关代码块(为简单起见,删除了异常处理)

private void processHibernateSaves(){
如果(!savesHibernate.isEmpty()){
迭代器jobIter=savesHibernate.Iterator();
while(jobIter.hasNext()){
DatabaseJobEvent job=jobIter.next();
Session Session=HibernateUtil.currentSession();
tx=session.beginTransaction();
for(PersistentObject对象:job.getObjects()){
if(obj.isSavedInDatabase()){
更新会议(obj);
}否则{
session.save(obj);
}
}

tx.commit();//Java不提供CopyOnWriteHashMap实现,但请查看是否可以使用jersey impl

您需要将其克隆传递给hibernate API

或者编写自己的实现

向我们显示保存集合的代码。请发布相关代码。Collections.synchronizeXXX不够。请改用java.util.concurrent.CopyOnWriteArrayList。此外,最好在保存期间禁止修改集合。在java中显示ConcurrentSkipListMap
private void processHibernateSaves() {
    if (!savesHibernate.isEmpty()) {            
        Iterator<DatabaseJobEvent> jobIter = savesHibernate.iterator();
        while (jobIter.hasNext()) {
            DatabaseJobEvent job = jobIter.next();
            Session session = HibernateUtil.currentSession();
            tx = session.beginTransaction();
            for (PersistentObject obj : job.getObjects()) {
                if (obj.isSavedInDatabase()) {
                    session.update(obj);
                } else {
                    session.save(obj);
                }
            }
            tx.commit(); //<-- Error is thrown at this point
            session.clear();
            for (PersistentObject obj : job.getObjects()) {
                synchronized (obj) {
                    obj.setSavedInDatabase(true);
                }
            }
            job.setExecuted(true);
            jobIter.remove();
        }
    }
}