繁体   English   中英

Hibernate抛出ConcurrentModificationException

[英]Hibernate throwing a ConcurrentModificationException

我写了一些测试,因为我一直工作在一个持久性层和我碰到一个例外是说我有对付,一个ConcurrentModificationException的 ,它的发生在麻烦org.hibernate.mapping.Table.cleanseUniqueKeyMap(Table.java:291)
原来是这行代码:

final Map.Entry<String,UniqueKey> uniqueKeyEntry = uniqueKeyEntries.next();

经过一些研究,我发现该异常是由一个线程在对该线程进行迭代时修改此集合引起的。 话虽这么说,我觉得我没有做任何事情正在导致这一切有关故障排除的建议?

顺便说一句,即时通讯使用hibernate 4.1.5 Idk是否清除任何内容。 这是我的测试:

@Test
public void testCreateMobsterUser() {
   try {            
       final MobsterUserDAO test = new MobsterUserDAO(); //throws exception
       //does stuff w/ return value...

如您所见,我们尝试初始化dao。

public MobsterUserDAO() {
    super(MobsterUser.class);
}

好吧,这并没有给我们带来太多好处,所以让我们看一下通用的dao构造函数,看看是否在其中看到了问题。

public MobsterBaseHibernateDAO(final Class<T> clazz) {
    this.clazz = clazz;
    //This next line is where the exception is actually occuring
    final EntityManagerFactory factory = Persistence.createEntityManagerFactory("mobsterdb");
    this.manager = (HibernateEntityManager) factory.createEntityManager();
}

现在,我不确定Persistance.createEntityManagerFactory是什么类型的兔子洞,但这是在异常发生之前执行的代码的最后一行。

当您在for-each循环中迭代集合,并在其他地方更改集合时,会发生并发修改。 常见的解决方案之一是使用Iterator而不是for-each循环。 或者让您的收藏夹处于synchronized块中。

有很多关于它的资源:

避免ConcurrentModificationException ,它说:

  1. 您可以将列表转换为数组,然后在数组上进行迭代。 这种方法适用于中小型列表,但是如果列表很大,则对性能的影响很大。

  2. 您可以通过将列表放在同步块中来在迭代时锁定列表。 不建议使用此方法,因为它将停止多线程的好处。

  3. 如果使用的是JDK1.5或更高版本,则可以使用ConcurrentHashMap和CopyOnWriteArrayList类。 这是推荐的方法。

也:

并发修改异常
如何调试ConcurrentModificationException?

由于在Hibernate内部内部整理期间这似乎是一个例外,所以我认为这是一个错误。 在Google上进行的快速搜索确实显示了最近报道的JIRA

提出了一项解决方案,但不知道何时发布。

希望这可以帮助!

发生这种情况的原因是,您的循环遍历了一个集合,然后在循环内的某个地方,您更改了要遍历的集合,然后尝试恢复循环,就好像什么都没有改变一样。

我发生了同样的事情:

for(UserJPA jpa : jpaList){
    if(jpa satisfies a condition){
        jpaList.remove(jpa);
    }
}

问题是您无法修改要遍历的列表。 在我的情况下,我选择的解决方案是在修改原始列表的同时创建一个新列表(原始副本)以对其进行迭代:

List<UserJPA> iterationList = new ArrayList<UserJPA>(jpaList);
for(UserJPA jpa : iterationList){
    if(jpa satisfies a condition){
        jpaList.remove(jpa);
    }
}

希望能有所帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM