【问题标题】:Hibernate OGM Aggregate Query result fields not working with Wrapper Types休眠 OGM 聚合查询结果字段不适用于包装器类型
【发布时间】:2018-01-18 11:04:50
【问题描述】:

我正在使用 Hibernate OGM (5.2.0.Alpha1) 和 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;
    }

服务层....(错误)

@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

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

如果我将 totalStones 类型设置为 Wrapper 类型(如 Integer、Double),则会出现错误, 所以我必须将该字段类型设置为 int 或 double。

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

我说的对吗????

【问题讨论】:

  • 我不明白这个查询: String query = "db.jangad.aggregate({'$project': { 'totalStones': { '$size':'$setOfSalesStoneCharacteristics' }}} , { '$match' : { '_id' :ObjectId('5a60784e8daff90498ba74e4')} } )";
  • 一个 Jangad 有多个石头(SalesStoneCharacteristics),所以我想要 Jangad 中可用的石头总数,其中 id 为“5a60784e8daff90498ba74e4”... Mongobooster 结果为上述查询:_id:ObjectId('5a60784e8daff90498ba74e4' )totalStones:10(数据类型Int32)错误如下:org.bson.json.JsonParseException:JSON阅读器期待一个值,但发现'db'。我明天会给你完整的错误。
  • 你看,错误不是你之前添加评论的地方,当你运行查询时。当你问一些事情时,如果你不准确,就会很混乱。无论如何,我解决了这个问题。

标签: java spring hibernate jpa hibernate-ogm


【解决方案1】:

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

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

这应该可行。

但如果你只对totalStones 感兴趣,你为什么不直接返回那个值呢? 它看起来像这样:

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

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

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

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

【讨论】:

  • 嗨,Davide,根据stackoverflow.com/questions/48056260/… 上的问题,实际上零不适用于当前版本。
  • 嗨,Davide,根据stackoverflow.com/questions/48056260/… 上的问题,实际上零不适用于当前版本。所以如果我执行像“db.jangad.aggregate([{'$project':{'_id': 0}}])”这样的简单查询,那么它会给出如下错误...错误:org.bson.json.JsonParseException :JSON 阅读器期待一个值,但找到了 'db'。在 org.bson.json.JsonReader.readBsonType(JsonReader.java:243)
  • 另一个要求:如果我想通过单个查询获得“jangad 中的石头总数加上 jangad 中的总块数”,那么我必须使用单个查询的对象插入字段..否则,如果我使用单个字段,我必须为此要求执行 3 个不同的查询..
  • 对,如果 _id 为 0,它将无法与稳定版本一起使用,但可以在 master 上使用。它将在下一个版本中使用。
  • 我不明白使用对象更改将如何更改您需要运行的查询数。另外,我认为我们不应该在 StackOverflow 评论部分讨论这个问题。如果您有更多未解决的问题,请在 Hibernate OGM 论坛或 HipChat 频道上提问:hibernate.org/community
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-16
  • 1970-01-01
  • 1970-01-01
  • 2020-04-08
  • 2015-01-26
相关资源
最近更新 更多