You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Hibernate新增数据后无法实时显示数据库记录问题求助

Hibernate新增Category后UI表格未实时更新问题排查

我是Hibernate框架新手,采用DAL、BLL、UI三层架构实现新增Category对象到数据库的功能,数据已成功入库,但点击添加按钮后表格未实时更新,必须重启程序才能看到新记录,怀疑是flush()或clear()的使用问题,恳请指导。


DAL层代码

构造方法

public class ImportProductDAL {
    private Session session;

    public ImportProductDAL() {
        session = HibernateUtil.getSessionFactory().openSession();
        session.beginTransaction();
    }
...
}

获取Category列表方法

public ArrayList<Category> categoryList(){
        Query query = session.createQuery("from Category", Category.class);
        ArrayList<Category> categories = (ArrayList<Category>) query.list();
        return categories;
    }

新增Category方法

public boolean createCategory(Category c) {
        session.persist(c);
        session.flush();
        session.clear();
        return session.getTransaction().getStatus() == TransactionStatus.COMMITTED;
    }

BLL层代码

获取Category列表方法

public ArrayList<Category> catgoryList(){
        return ipDAL.categoryList();
}

新增Category方法

public boolean createCategory(Category c){
        return ipDAL.createCategory(c);
}

UI层代码

加载表格数据方法

private void categoryList() {
        table.setModel(model(ipBLL.catgoryList()));
}

构建表格模型方法

private DefaultTableModel model(ArrayList list) {
        String[] columnNames = {"ID", "Category Name", "Description"};
        Object[][] data = new Object[list.size()][3];
        for (int i = 0; i < list.size(); i++) {
            Category category = (Category) list.get(i);
            data[i][0] = category.getCatagoryID();
            data[i][1] = category.getName();
            data[i][2] = category.getDescription();
        }
        DefaultTableModel model = new DefaultTableModel(data, columnNames);
        return model;
}

添加按钮事件处理

private void btnAddActionPerformed(java.awt.event.ActionEvent evt) {                                       
        if (!txtCategory.getText().trim().equals("") && !txtDescription.getText().trim().equals("")) {
            Category newCategory = new Category();
            newCategory.setName(txtCategory.getText());
            newCategory.setDescription(txtDescription.getText());

            int result = JOptionPane.showConfirmDialog(this, "Add new category?",
                    "Confimation",
                    JOptionPane.YES_NO_OPTION,
                    JOptionPane.QUESTION_MESSAGE);
            if (result == JOptionPane.YES_OPTION) {
                if (ipBLL.createCategory(newCategory)) {
                    JOptionPane.showMessageDialog(this,
                            "Category added successfully!");
                    categoryList();
                }
            }

        }
}

问题原因及解决步骤

  1. 事务未提交:DAL构造方法开启了事务,但createCategory仅调用flush()同步操作到连接,未提交事务。未提交的事务对当前会话后续查询、其他会话都是不可见的。

    • 修改createCategory方法,添加事务提交:
      public boolean createCategory(Category c) {
              session.persist(c);
              session.getTransaction().commit(); // 提交事务
              session.flush();
              session.clear();
              return session.getTransaction().getStatus() == TransactionStatus.COMMITTED;
          }
      

    注意:事务提交后若需复用Session,需重新开启事务;更稳妥的方式是每次操作使用独立Session。

  2. Session缓存复用问题:全局复用的Session会保留一级缓存,后续查询会优先读取缓存而非最新数据库数据。

    • 改为每次操作使用独立Session,避免缓存干扰:
      public boolean createCategory(Category c) {
              try (Session session = HibernateUtil.getSessionFactory().openSession()) {
                  Transaction tx = session.beginTransaction();
                  session.persist(c);
                  tx.commit();
                  return tx.getStatus() == TransactionStatus.COMMITTED;
              } catch (Exception e) {
                  e.printStackTrace();
                  return false;
              }
          }
      
      public ArrayList<Category> categoryList(){
              try (Session session = HibernateUtil.getSessionFactory().openSession()) {
                  Query query = session.createQuery("from Category", Category.class);
                  return (ArrayList<Category>) query.list();
              } catch (Exception e) {
                  e.printStackTrace();
                  return new ArrayList<>();
              }
          }
      
  3. 确认UI刷新线程:Swing组件必须在事件调度线程(EDT)操作,你的按钮事件本身处于EDT中,categoryList()调用没问题,若后续引入异步操作需注意切换到EDT执行刷新。

内容的提问来源于stack exchange,提问作者Phạm Phú Khánh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 08:02:52