首页 > 解决方案 > 如何避免 java.util.ConcurrentModificationException

问题描述

我在这个应用程序中使用 Hibernate。我正在尝试将数据从数据库调用到 jTable。当数据库为空时,代码正在编译,但是当我将数据添加到 mysql 表程序时抛出 java.util.ConcurrentModificationException。

 public FrmMain() {
    initialize();
    getData();
 }

 public void getData() {
    
    model = (DefaultTableModel) tblBookList.getModel();
    
    List<Book> books = new ArrayList<>(bookManager.getBook());
    
    ListIterator<Book> listIterator = books.listIterator();
      
    while(listIterator.hasNext()) {
      
      Book book = listIterator.next();
      
      Object[] row = { book.getName(), book.getAuthor(), book.getPublisher(),
      book.getPage(), book.getTranslator(), book.getPublishYear(), book.getType()
      };
      
      model.addRow(row);
      
    }
    
}

我的数据访问代码。也许问题就在这里

public class MySqlBookDal implements IBookDal {

SessionFactory factory = new Configuration()
        .configure("mysqlHibernate.cfg.xml")
        .addAnnotatedClass(Book.class)
        .buildSessionFactory();

Session session = factory.getCurrentSession(); 

public List<Book> select() {
    
    List<Book> books = new CopyOnWriteArrayList<Book>();
    
    try {
        
        session.beginTransaction();
        
        books = session.createQuery("from Book").getResultList();
        
        for(Book book: books) {
            books.add(book);
        }
        
        session.getTransaction().commit();
        
    } finally {
        factory.close();
    }
    
    return books;
}

有人可以帮助我吗?堆栈跟踪:

ERROR: Connection leak detected: there are 1 unclosed connections upon 

shutting down pool jdbc:mysql://localhost:3306/book?useUnicode=true&useLegacyDatetimeCode=false&serverTimezone=Turkey
java.util.ConcurrentModificationException
    at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1013)
    at java.base/java.util.ArrayList$Itr.next(ArrayList.java:967)
    at com.github.bookManagementSystem.dataAccess.MySqlBookDal.select(MySqlBookDal.java:32)
    at com.github.bookManagementSystem.business.BookManager.getBook(BookManager.java:20)
    at com.github.bookManagementSystem.FrmMain.getData(FrmMain.java:98)
    at com.github.bookManagementSystem.FrmMain.<init>(FrmMain.java:90)
    at com.github.bookManagementSystem.FrmMain$1.run(FrmMain.java:76)
    at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:316)
    at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:770)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
    at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:740)
    at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

标签: javahibernatejava.util.concurrent

解决方案


您正在用另一个列表替换 的值,books然后循环尝试将新列表附加books到自身中 - 因此是 ConcurrentModificationException。

假设 getResultList() 返回一个 List 你需要做的就是将结果直接附加到书籍而不重新分配:

books.addAll(session.createQuery("from Book").getResultList());

// books = session.createQuery("from Book").getResultList();
// for(Book book: books) {
//         books.add(book);
// }

推荐阅读