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
相关产品推荐
相关产品推荐

