Spring-data-mongo unable to instantiate java.util.List using Constructor
Asked Answered
D

3

8

Using spring-data-mongodb-1.5.4 and mongodb-driver-3.4.2

I've a class Hotel

    public class Hotel {

        private String name;
        private int pricePerNight;
        private Address address;
        private List<Review> reviews;
//getter, setter, default constructor, parameterized constructor 

Review class :

public class Review {

    private int rating;
    private String description;
    private User user;
    private boolean isApproved;
 //getter, setter, default constructor, parameterized constructor 

When I am calling Aggregation.unwind("reviews"); it throws

org.springframework.data.mapping.model.MappingInstantiationException: Failed to instantiate java.util.List using constructor NO_CONSTRUCTOR with arguments

UnwindOperation unwindOperation = Aggregation.unwind("reviews");
Aggregation aggregation = Aggregation.newAggregation(unwindOperation);
AggregationResults<Hotel> results=mongoOperations.aggregate(aggregation,"hotel", Hotel.class);

I see this question but does't help me.

How to resolve this?

Defective answered 10/9, 2017 at 10:49 Comment(1)
9/10 times you really just want a plain BSON object like Document.class or DBObject.class for the aggregation output. Aggregations change the output shape by definition of what they are meant to do. Typically you just don't need a strict type for output, unless you really need some custom serialization. For everything else, just use the generics. That's what they are there for.Golda
B
13

When you $unwind reviews field, query's return json structure does not match with your Hotelclass anymore. Because $unwindoperation makes reviews a sub object instead of a list. If you try your query in robomongo or some other tools, you can see your return object is like that

{
  "_id" : ObjectId("59b519d72f9e340bcc830cb3"),
  "id" : "59b23c39c70ff63135f76b14",
  "name" : "Signature",
  "reviews" : {
    "id" : 1,
    "userName" : "Salman",
    "rating" : 8,
    "approved" : true
  }
}

So you should use another class instead of Hotellike UnwindedHotel

public class UnwindedHotel {

    private String name;
    private int pricePerNight;
    private Address address;
    private Review reviews;
}

UnwindOperation unwindOperation = Aggregation.unwind("reviews");
Aggregation aggregation = Aggregation.newAggregation(unwindOperation);
AggregationResults<UnwindedHotel> results=mongoOperations.aggregate(aggregation,"hotel", UnwindedHotel.class);
Breakable answered 10/9, 2017 at 11:1 Comment(3)
You saved me again :)Defective
@MehrajMalik Happy to help. And a general suggestion which I do for my queries. First build them as native mongodb query and try it directly via robomongo etc. Then code it into spring-data. So you can be sure your query works and return values as expected.Breakable
Thanks for the golden tip.Defective
F
0

It occurs to me a very different problem making me crazy for long time a day ago and I think it could be very useful to share here even if it is not about unwind:

  • at the beginning I design a model with java + mongoDB in which I put some fields in a key inside a document and made several tests, for example {"header":{"key":"first", "value": 4}}
  • then I changed my mind and think not to have simple nested objects but a list of them to be more general such as {"header":[{"key":"first", "value": 4}] }

When I was working only with new documents all was running fine, but then making more general tests I continuously had crashes with this mongodb error about List because in my DB I had old documents without list but with simple objects I forgot to remove and which were in conflict with the new model wanting a list.

Simple had I to clean DB and starting tests from scratch.

Femmine answered 23/6, 2021 at 9:34 Comment(0)
C
0

U dont have to clean the Db ,just rename the previous collection and create a new collection with the name mentioned in the properties/yml file on your project and save it in the mongoDb database.

then run your project and save the new data using the save Api and u can observe the changes from comparing both the collections.

Czechoslovakia answered 17/5 at 11:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.