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

基于Hibernate的CRUD GUI出现IndexOutOfBoundsException问题求助

解决Hibernate CRUD GUI中的IndexOutOfBoundsException异常

问题概述

你在基于Hibernate开发基础CRUD GUI时,点击搜索按钮触发了java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0异常,异常指向代码中getQuantity().get(i)的调用位置。你尝试将Items list改为List<Items>类型,但由于搜索仅返回单个结果,这个调整并没有解决问题。

原因分析

从异常栈信息可以明确定位问题:

  1. 空列表直接取值导致越界:异常发生在ArrayList.get()方法,说明getQuantity()返回的是一个空列表,但你在代码中直接调用get(i)(i=0)获取元素,自然触发索引越界。
  2. getQuantity()查询逻辑的局限性:该方法的HQL是查询所有商品的交易数量统计,当你搜索的商品没有对应的Advicenote或Transactions记录时,这个查询会返回空列表。
  3. 空值判断错误:代码中if (list.equals(null))的写法存在隐患——如果list本身是null,调用equals(null)会直接抛出NullPointerException,正确的空值判断应该是list == null。

解决方案建议

针对上述问题,给出以下分步修复方案:

1. 先判断列表是否为空,再安全取值

在搜索方法的循环逻辑中,先获取getQuantity()的返回列表,检查列表长度后再取值,避免直接索引访问:

// 先获取数量列表,避免重复调用方法
List<ItemAndQuantity> quantityList = getQuantity();
for (int i = 0; i < 1; i++) {
    Object[] rowData;
    if (quantityList.size() > i) {
        // 有数量记录时正常取值
        ItemAndQuantity quantity = quantityList.get(i);
        rowData = new Object[]{
            list.getName(), 
            list.getCategory().getName(), 
            quantity.getQuantity(), 
            list.getNetPrice(), 
            list.getNetPrice()*(list.getVatRate()+1), 
            quantity.getQuantity()*list.getNetPrice(), 
            list.getNetPrice()*(list.getVatRate()+1)*quantity.getQuantity()
        };
    } else {
        // 无数量记录时显示0
        rowData = new Object[]{
            list.getName(), 
            list.getCategory().getName(), 
            0, 
            list.getNetPrice(), 
            list.getNetPrice()*(list.getVatRate()+1), 
            0, 
            0
        };
    }
    dtm.addRow(rowData);
}

2. 修复空值判断逻辑

把错误的list.equals(null)替换为正确的list == null:

if (list == null) {
    JOptionPane.showMessageDialog(null, "No results");
} else {
    // 后续表格填充逻辑
}

3. 优化getQuantity()的查询精度

当前getQuantity()查询所有商品的数量,效率低且容易出现空结果。可以修改为针对当前搜索到的商品单独查询数量,同时使用左连接和coalesce函数确保即使无交易记录也返回0:

public List<ItemAndQuantity> getQuantity(int itemId) { // 增加itemId参数
    List<ItemAndQuantity> quantity = new ArrayList<>();
    try {
        session = sessionFactory.openSession();
        transaction = session.beginTransaction();
        // 左连接确保无交易时也能返回数据,coalesce将null转为0
        Query query = session.createQuery(
            "select coalesce(sum(t.flow * a.inOrOut), 0) " +
            "from Items i " +
            "left join i.transactions t " +
            "left join t.advicenote a " +
            "where i.itemId = :itemId " +
            "group by i.itemId"
        );
        query.setParameter("itemId", itemId);
        quantity.addAll(query.list());
        transaction.commit();
    } catch (HibernateException e) {
        if (transaction != null) {
            transaction.rollback();
        }
        e.printStackTrace();
    } finally {
        if (session != null && session.isOpen()) {
            session.close();
        }
    }
    return quantity;
}

然后在搜索方法中调用时传入当前商品的ID:

List<ItemAndQuantity> quantityList = getQuantity(list.getItemId());

4. 完善Session资源管理

在搜索方法中,Session的关闭应该放在finally块中,避免异常时Session无法正常关闭:

Session session = null;
Transaction transaction = null;
try {
    session = sessionFactory.openSession();
    transaction = session.beginTransaction();
    Criteria criteria = session.createCriteria(Items.class);
    Items list = (Items) criteria.add(Restrictions.eq("name", name).ignoreCase()).uniqueResult();
    transaction.commit();
    
    // 后续表格填充逻辑...
} catch (Exception e) {
    if (transaction != null) {
        transaction.rollback();
    }
    JOptionPane.showMessageDialog(null, e.getMessage());
    e.printStackTrace();
} finally {
    if (session != null && session.isOpen()) {
        session.close();
    }
}

内容的提问来源于stack exchange,提问作者Fluellen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 03:59:00