-1

I have a class which contains other some properties of another classes and when I try to convert from json to my class, there is an error displayed.

This is my class:

import org.jongo.marshall.jackson.oid.MongoObjectId;
import org.json.JSONObject;

import java.util.List;

public class BusinessTravelDTO {
  @MongoObjectId
  private String id;

  private String travelerId;

  private BusinessTravelStatus status;

  List<FlightDTO> flights;

  List<HotelDTO> hotels;

  List<CarDTO> cars;

  public BusinessTravelDTO() { }

  public BusinessTravelDTO(JSONObject data) {
    this.travelerId = data.getString("travelerId");
    this.status =  BusinessTravelStatus.valueOf(data.getString("status"));
    this.flights = HandlerUtil.getInputFlights(data.getJSONArray("flights"));
    this.hotels = HandlerUtil.getInputHotels(data.getJSONArray("hotels"));
    this.cars = HandlerUtil.getInputCars(data.getJSONArray("cars"));
  }

  public JSONObject toJson() {
    return new JSONObject()
            .put("id", this.id)
            .put("travelerId", this.travelerId)
            .put("status", this.status)
            .put("flights", this.flights)
            .put("hotels", this.hotels)
            .put("cars", this.cars);
  }

And here is where I try to convert to class:

 public static JSONObject acceptBusinessTravel(JSONObject input) {
    String btId = getStringField(input, "id");
    MongoCollection businessTravels = getBTCollection();

     // Here is the problem...
    BusinessTravelDTO bt = businessTravels.findOne(new ObjectId(btId)).as(BusinessTravelDTO.class);
    bt.setStatus(BusinessTravelStatus.Accepted);

    businessTravels.save(bt);

    return new JSONObject().put("message", "The business travel has been ACCEPTED by your manager. Check your email.");
  }

Here is the error I receive:

"error": "org.jongo.marshall.MarshallingException: Unable to unmarshall result to class path.data.BusinessTravelDTO from content { \"_id\" : { \"$oid\" : \"59d6905411d58632fd5bd8a5\"} , \"travelerId\" 

In jongo docs is specified that the class should have an empty constructor... http://jongo.org/#mapping I have 2 constructors, I have tried also with @JsonCreator, but no success... :(
Do you have an idea why it doesn't convert? Could it be something related to fields inside BusinesTravelDTO like List CarDTO for ex ?

V. Sambor
  • 12,361
  • 6
  • 46
  • 65
  • The JSON text appears to have an `_id` field of some object type with a `$oid` field, while your `BusinessTravelDTO` has an `id` field of type `String`. How did you expect that to work? --- I am a bit confused though, since I can't see where in the code you're doing the marshalling. What was the point of showing us the `acceptBusinessTravel()` method? – Andreas Oct 05 '17 at 23:10
  • @Andreas maybe you missed @ MongoObjectId, this anotation allow you to use mongo object id in class, but if you don't put it, the '_id' is anyway created behind the scenes... :-| – V. Sambor Oct 05 '17 at 23:21
  • I saw it, but what does that have to do with the JSON? – Andreas Oct 06 '17 at 04:24

1 Answers1

0

I finnally found the solution;

There is needed an empty constructor in all classes FlightDTO, HotelDTO, CarDTO plus I should rewrite the toJson method as following:

public JSONObject toJson() {
    JSONObject obj = new JSONObject().put("id", this.id).put("travelerId", this.travelerId).put("status", this.status);

    if (flights != null) {
      JSONArray flightArray = new JSONArray();
      for (int i = 0; i < flights.size(); ++i) {
        flightArray.put(flights.get(i).toJson());
      }
      obj.put("flights", flightArray);
    }

    if (hotels != null) {
      JSONArray hotelArray = new JSONArray();
      for (int i = 0; i < hotels.size(); ++i) {
        hotelArray.put(hotels.get(i).toJson());
      }
      obj.put("hotels", hotelArray);
    }

    if (cars != null) {
      JSONArray carArray = new JSONArray();
      for (int i = 0; i < cars.size(); ++i) {
        carArray.put(cars.get(i).toJson());
      }
      obj.put("cars", carArray);
    }
    return obj;
  }

And this is the FlightDTO;

public class FlightDTO {
  @MongoObjectId
  private String id;

  private String departure;
  private String arrival;
  private String airline;
  private Double price;

  public FlightDTO() {
  }

  public FlightDTO(JSONObject data) {
    this.departure = data.getString("departure");
    this.arrival = data.getString("arrival");
    this.airline = data.getString("airline");
    this.price = data.getDouble("price");
  }

  public JSONObject toJson() {
    return new JSONObject()
            .put("id", this.id)
            .put("departure", this.departure)
            .put("arrival", this.arrival)
            .put("airline", this.airline)
            .put("price", this.price);
  }
}

now it works well! :)

V. Sambor
  • 12,361
  • 6
  • 46
  • 65