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

Sugar ORM批量保存仅存1条数据问题排查求助

Sugar ORM保存多条记录仅返回1条的问题排查与解决

看起来你遇到了Sugar ORM中批量保存数据的常见陷阱,我来帮你分析原因并给出解决方案:

问题重现

你定义的实体类:

public class READINGTBL extends SugarRecord {
    @Unique
    public String geographicalCode, sCode,subscriberId, fullName,lastReadingDate,lastReadingDigit,dailyConsumptionAverage,readingStatus,waterMeterStatus,readingType,familyPopulation,waterConsumptionDetail,propertyUsageDetail,splitDiameter,debt,phone,bodyNo,numberOfDigits,postalCode,address,splitStatus,calculationType,physicalArchiveNo;
    public READINGTBL(){}
    public READINGTBL(String geographicalCode,String sCode,String subscriberId){
        this.geographicalCode=geographicalCode;
        this.sCode=sCode;
        this.subscriberId=subscriberId;
    }
}

批量保存代码:

SugarContext.init(adapter);
List<READINGTBL> mySave=new ArrayList<>();
for(int i=0;i<100;i++) {
    READINGTBL models=new READINGTBL("","","","");
    models.save();
}

查询代码(注意这里有个明显笔误):

List<READINGTBL> test_find=LOGINTBL.listAll(READINGTBL.class);
return test_find.size();

核心原因

问题出在**@Unique注解的误用**:

  • 在Java语法中,当你在一行声明多个字段并在开头添加注解时,这个注解会作用于该行的所有字段。也就是说,你代码里的geographicalCode、sCode、subscriberId等所有后续字段都被标记为@Unique约束。
  • Sugar ORM的save()方法逻辑是:如果存在违反唯一约束的记录,会执行更新操作而不是插入新记录。你循环创建的100个对象,所有被标记为唯一的字段都是空字符串"",第一条记录插入成功后,后续99次save()都会因为唯一约束冲突,转而更新已存在的那条记录,最终数据库里只剩1条数据。

另外,你的查询代码里LOGINTBL.listAll(READINGTBL.class)是笔误,应该改为READINGTBL.listAll(READINGTBL.class),不过这不是返回1条的核心原因。

解决方案

根据你的业务需求,选择以下一种方式修复:

1. 移除不必要的唯一约束

如果你不需要这些字段具有唯一性,直接删除@Unique注解即可:

public class READINGTBL extends SugarRecord {
    public String geographicalCode, sCode,subscriberId, fullName,lastReadingDate,lastReadingDigit,dailyConsumptionAverage,readingStatus,waterMeterStatus,readingType,familyPopulation,waterConsumptionDetail,propertyUsageDetail,splitDiameter,debt,phone,bodyNo,numberOfDigits,postalCode,address,splitStatus,calculationType,physicalArchiveNo;
    // 构造方法不变
}

这样批量保存100个空对象时,会生成100条独立记录。

2. 仅给需要唯一的字段添加@Unique

如果只有特定字段需要唯一(比如subscriberId),单独给该字段添加注解:

public class READINGTBL extends SugarRecord {
    public String geographicalCode, sCode;
    @Unique
    public String subscriberId;
    public String fullName, lastReadingDate, lastReadingDigit, ...; // 其他字段保留原样
    // 构造方法不变
}

3. 使用联合唯一约束(如果需要多字段组合唯一)

如果你的业务需求是geographicalCode + sCode + subscriberId三者组合唯一,而不是每个字段单独唯一,那么用类级别的@UniqueConstraint替代字段级的@Unique:

@UniqueConstraint(columnNames = {"geographicalCode", "sCode", "subscriberId"})
public class READINGTBL extends SugarRecord {
    public String geographicalCode, sCode,subscriberId, fullName,...; // 所有字段都去掉@Unique
    // 构造方法不变
}

这种情况下,只要三个字段的组合值不重复,就能成功插入多条记录。

4. 确保保存的唯一字段值不重复

如果你确实需要这些字段单独唯一,那么在循环创建对象时,给每个对象的唯一字段赋予不同的值,比如:

for(int i=0;i<100;i++) {
    READINGTBL models=new READINGTBL("geo_"+i, "s_"+i, "sub_"+i);
    models.save();
}

最后别忘了修正查询代码中的笔误,把LOGINTBL改为READINGTBL。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:08:04