Hibernate OGM聚合查询结果字段无法适配Java包装类型问题
Hibernate OGM聚合查询结果与Java包装类型的映射问题
针对你的问题,是的,在Hibernate OGM 5.2.0.Alpha1这个早期版本中,确实存在MongoDB聚合查询结果无法适配Java包装类型Integer的问题,切换为int基本类型能正常工作,这是该版本OGM类型映射机制的局限导致的。
问题原因分析
Hibernate OGM 5.2.0.Alpha1作为预览版本,对MongoDB原生聚合操作的结果处理逻辑还不够完善:
- 当使用
$size操作返回集合长度时,MongoDB会返回int32类型的数值。OGM在将这个数值映射到Integer包装类型时,没有正确处理类型转换的边界情况(比如空值兼容、类型匹配逻辑); - 而
int作为基本类型,Java的自动装箱/拆箱机制会自动完成MongoDB数值到int的转换,绕过了OGM包装类型映射的bug。
可行的解决方案
临时方案(你已采用)
保持字段为int基本类型,如果业务场景需要处理null值,可以在实体类中设置默认值(比如private int totalStones = 0;),避免后续空指针问题。升级到稳定版本
Hibernate OGM的后续稳定版本(比如5.2.x Final版本,或更高的5.3+版本)已经修复了大量类型映射的bug,包装类型的兼容性得到了明显提升。升级后应该可以直接使用Integer类型接收聚合查询结果。自定义类型映射(针对无法升级的场景)
如果暂时无法升级版本,可以实现Hibernate的UserType接口,自定义Integer类型与MongoDB数值的转换逻辑,手动处理包装类型的适配:public class CustomIntegerType implements UserType { // 实现nullSafeGet、nullSafeSet等方法,处理MongoDB数值到Integer的转换 }然后在实体类字段上标注
@Type(type = "com.yourpackage.CustomIntegerType")。
参考代码(你的示例)
实体类Jangad(修改前):
@Entity @Table(name = "jangad") @JsonInclude(Include.NON_EMPTY) public class Jangad { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @JsonSerialize(using = ToStringSerializer.class) public ObjectId id; public String name; @OneToMany(mappedBy = "jangad") public Set<SalesStoneCharacteristics> setOfSalesStoneCharacteristics; // 注:Integer类型无法适配聚合查询结果 public Integer totalStones; // getter、setter方法 }
服务层聚合查询:
@Transaction public void executeQuery() { String query = "db.jangad.aggregate({'$project': { 'totalStones': { '$size':'$setOfSalesStoneCharacteristics' }}} , { '$match' : { '_id' :ObjectId('5a60784e8daff90498ba74e4')} } )"; List<Jangad> listOfJangads = jangadDao.executeQuery(query, null, null, new Jangad()); if (!SalesUtils.isListIsNullOrEmpty(listOfJangads)) { System.out.println(listOfJangads.get(0).getTotalStones()); // 此处报错 } }
内容的提问来源于stack exchange,提问作者vishvas4u
相关产品推荐
相关产品推荐

