簡體   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