Hibernate OGM聚合查询结果字段不适用于包装器类型 [英] Hibernate OGM Aggregate Query result fields not working with Wrapper Types

查看:109
本文介绍了Hibernate OGM聚合查询结果字段不适用于包装器类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Mongodb(3.4)中使用Hibernate OGM(5.2.0.Alpha1)

I am using Hibernate OGM (5.2.0.Alpha1) with Mongodb (3.4)

示例:

@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;

    // Note : Integer data type for this not working with aggregation result.
    public Integer totalStones;

    getter....
    setter....

}


@Entity
@Table(name = "sales_stone_details")
@JsonInclude(Include.NON_EMPTY)
// @JsonFilter(value = SalesUtils.MY_CUSTOM_FILTER_FOR_SURAT_POLISH_STONES)
public class SalesStoneCharacteristics {
     @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "SALES_STONE_CHARACTERISTICS_ID", unique = true, nullable = false)
    @JsonSerialize(using = ToStringSerializer.class)
    public ObjectId id;

    private String name;

    @ManyToOne
    @JsonIgnore
    private Jangad jangad;

    setter....
    getter....
}

道层...

public <T> List<T> executeQuery(String query, Integer startPosition, Integer noOfRecords, T t) {
        List<T> listOfT = new ArrayList<>();

        if (SalesUtils.isObjectisNullOrEmpty(startPosition, noOfRecords)) {
            listOfT = entityManager.createNativeQuery(query.toString(), t.getClass()).getResultList();
        } else {
            listOfT = entityManager.createNativeQuery(query.toString(), t.getClass()).setFirstResult(startPosition)
                    .setMaxResults(noOfRecords).getResultList();
        }
        return SalesUtils.isListIsNullOrEmpty(listOfT) ? new ArrayList<>() : listOfT;
    }

服务层....(错误)

Service Layer....(Error)

@Transaction
public void executeQuery() {

    String query = "db.jangad.aggregate({'$project': { 'totalStones': { '$size':'$setOfSalesStoneCharacteristics' }}} , { '$match' : { '_id' :ObjectId('5a60784e8daff90498ba74e4')} } )";

    List<Jangad> listOfJangads = jangadDao.executeQuery(sb.toString(), null, null, new Jangad());
    if (!SalesUtils.isListIsNullOrEmpty(listOfJangads)) {                   
        System.out.println(listOfJangads.get(0).getTotalStones()) // Error
    }
}

临时解决方案: 将totalStones的字段类型从Integer更改为Jangad.java的int

Temporary Solution : Changed field type of totalStones from Integer to int of Jangad.java

服务层的错误说明....(错误)

Error Explaination of Service Layer....(Error)

在这里,如果我将totalStones类型设置为Wrapper类型(例如Integer,Double),则会出现错误, 所以我必须将字段类型设置为int或double.

here if i set totalStones type as Wrapper type (like Integer,Double) then it gives error, so i must put that field types to int or double.

似乎聚合结果不适用于任何Java Wrapper类型.

It seems like aggregation result is not working with any Java Wrapper type.

我说的对吗?????

Is i am right?????

推荐答案

此查询存在两个问题. 第一个是您没有将其作为数组传递,因此解析器引发了异常.您应该像这样添加[]:

There are two problems with this query. The first one is that you are not passing it as an array and therefore the parser thrown an exception. You should add the [ and ] like so:

String query = "db.jangad.aggregate([{'$project': { 'totalStones': { '$size':'$setOfSalesStoneCharacteristics' }}} , { '$match' : { '_id' :ObjectId('5a60784e8daff90498ba74e4')} }] )";

这应该有效.

但是,如果您只对totalStones感兴趣,为什么不只返回该值呢? 看起来像这样:

But if you are interested only to thetotalStones , why don't you just return that value? It will look like this:

String totalStones = "db.jangad.aggregate([{'$project': { 'totalStones': { '$size':'$setOfSalesStoneCharacteristics' }}} , { '$match' : { '_id' :ObjectId('5a60784e8daff90498ba74e4')} }, {'$project':{ '_id': 0}}] )";
Integer size = (Integer) em.createNativeQuery( query ).getSingleResult();

如果只需要特定的字段,则不必每次都创建一个对象,也不必在实体上映射totalStones字段.

You don't have to create an object every time if you only need specific fields, and you don't have to map the totalStones field on the entity.

编辑:由于存在识别0的错误,因此最后一个查询仅适用于Hibernate OGM 5.2.CR1之后的版本.

EDIT: Because of a bug in recognizing 0, this last query will only work for versions after Hibernate OGM 5.2.CR1

如果要/需要创建实体对象,请确保查询返回所有字段,否则OGM将创建不完整的对象.在这种情况下,Jangad将仅设置id和totalStones属性.

If you want/need to create the entity object, make sure that the query returns all the fields or OGM will create an incomplete object. In this case the Jangad will only have the id and the totalStones property set.

这篇关于Hibernate OGM聚合查询结果字段不适用于包装器类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆