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

Apache Ignite存储含集合对象时查询结果不一致问题咨询

问题根因
  1. Ignite分区模式下备份数为1时,每份数据会同时存储在1个主分区节点和1个备份分区节点。默认情况下SqlQuery会在所有持有该缓存数据的节点(含备份节点)执行查询,同一份数据会从主、备节点各返回一次。
  2. 你定义的PersonImpl类没有重写equals()和hashCode()方法,默认使用JDK的引用相等判断。当类包含HashMap、ArrayList这类可变集合属性时,主、备节点返回的同一份数据反序列化后是不同的对象实例,引用不相等就不会被自动去重,最终出现重复数据。移除集合属性后如果剩下的都是不可变基础类型/包装类型,刚好满足值相等判断逻辑,就不会出现重复。
  3. 备份数调整为0后,所有数据仅存于主分区节点,查询时只会返回一次,自然不会有重复问题。
解决方案
  • 方案1:显式指定查询不读取备份数据
    构建SqlQuery时添加setIncludeBackups(false)配置,仅从主分区节点拉取数据,从源头上避免重复数据返回,修改后的查询代码如下:
    public <V> List<V> sqlQuery(Class<V> persistentClass, String t){
        SqlQuery<K,V> sqlQuery = new SqlQuery<>(persistentClass,t);
        // 新增配置,不查询备份分区
        sqlQuery.setIncludeBackups(false);
        List<V> values = new ArrayList<>();
        try(QueryCursor<Entry<K,V>> queryCursor= getCache.query(sqlQuery)){
            for(Entry<K,V> entry : queryCursor){
                 values.add(entry.getValue());
            }
        }
        return values;
    }
    
    这里额外补充了QueryCursor的资源关闭逻辑,避免资源泄漏。
  • 方案2:重写实体类的equals()和hashCode()方法
    将所有业务上判断相等的属性都纳入方法计算逻辑,HashMap和ArrayList本身已经实现了基于内容的相等判断,直接调用即可,示例代码如下:
    import java.util.Objects;
    
    public class PersonImpl{
       private String name;
       private HashMap<Integer,String> attr = new HashMap<>();
       private HashMap<Integer,String> attr1 = new HashMap<>();
       private ArrayList<Integer> a;
       private ArrayList<Integer> b;
    
       @Override
       public boolean equals(Object o) {
           if (this == o) return true;
           if (o == null || getClass() != o.getClass()) return false;
           PersonImpl that = (PersonImpl) o;
           return Objects.equals(name, that.name) && Objects.equals(attr, that.attr) && Objects.equals(attr1, that.attr1) && Objects.equals(a, that.a) && Objects.equals(b, that.b);
       }
    
       @Override
       public int hashCode() {
           return Objects.hash(name, attr, attr1, a, b);
       }
    }
    
    重写完成后,查询结果可以通过values.stream().distinct().collect(Collectors.toList())手动去重,也能解决重复问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 06:36:00