0

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

Example:

@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....
}

Dao Layer...

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
    }
}

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

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

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.

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

Is i am right?????

vishvas4u
  • 41
  • 9
  • I don't understand this query: String query = "db.jangad.aggregate({'$project': { 'totalStones': { '$size':'$setOfSalesStoneCharacteristics' }}} , { '$match' : { '_id' :ObjectId('5a60784e8daff90498ba74e4')} } )"; – Davide D'Alto Jan 18 '18 at 14:50
  • One Jangad has multiple stones(SalesStoneCharacteristics) , so i want total number of stones available in Jangad which id is "5a60784e8daff90498ba74e4"... Mongobooster result for this above query : _id : ObjectId('5a60784e8daff90498ba74e4') totalStones : 10 (data type Int32) Error is below: org.bson.json.JsonParseException: JSON reader was expecting a value but found 'db'. i will give you complete error on tomorrow. – vishvas4u Jan 18 '18 at 15:01
  • You see, the error is not where you added the comment is before, when you run the query. When you ask something is very confusing if you are not precise. Anyway, I figure out the issue. – Davide D'Alto Jan 18 '18 at 15:54

1 Answers1

0

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')} }] )";

This should work.

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();

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.

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

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.

Davide D'Alto
  • 7,421
  • 2
  • 16
  • 30
  • Hi Davide , Actually zero is not working with current release version as per issue on https://stackoverflow.com/questions/48056260/hibernate-ogm-with-mongodb-count-query-with-gt-gte-lt-lte-not-working-with-l. – vishvas4u Jan 19 '18 at 04:22
  • Hi Davide , Actually zero is not working with current release version as per issue on https://stackoverflow.com/questions/48056260/hibernate-ogm-with-mongodb-count-query-with-gt-gte-lt-lte-not-working-with-l. so if i executed simple query like "db.jangad.aggregate([{'$project':{'_id' : 0}}])" then it gives errror like below... Error : org.bson.json.JsonParseException: JSON reader was expecting a value but found 'db'. at org.bson.json.JsonReader.readBsonType(JsonReader.java:243) – vishvas4u Jan 19 '18 at 04:28
  • Another Requirement : If i want to get "total number of stones in jangad plus total number of pieces in jangad plug total number of lot in jangad" with single query then i have to used object instread of single field.. Otherwise i have to execute 3 different query for this requirement if i used single field.. – vishvas4u Jan 19 '18 at 04:29
  • Right, if _id is 0 it won't work with the stable release but it will work on master. It will will work on the next release. – Davide D'Alto Jan 19 '18 at 11:54
  • I don't understand how using an object change will change the number of queries you need to run. Also, I don't think we should discuss this on StackOverflow comment section. If you have more open questions, ask them on the Hibernate OGM forum or HipChat channel: http://hibernate.org/community/ – Davide D'Alto Jan 19 '18 at 11:59
  • But OK, if that's your requirement than it might make sense to retrieve the whole object, just make sure to return all the fields. I'm not familiar enough with MongoDB queries, but I would expect to be able to sum the three fields using aggregation. – Davide D'Alto Jan 19 '18 at 12:04