Search code examples
javaspringmongodbspring-dataspring-data-mongodb

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


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?


Solution

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