Uploaded image for project: 'Camel'
  1. Camel
  2. CAMEL-10728

Camel MongoDB Multiple Insert issue

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Minor
    • Resolution: Fixed
    • 2.18.1
    • 2.19.1, 2.20.0
    • camel-mongodb
    • None

    Description

      I think there is a problem with multi-insert on MongoDB component as it fails to gracefully handle a BasicDBList. The logic below always sets the SingleInsert flag to true if the type converter is able to convert the exchange to a DBObject interface. This is implemented by BasicDBList and BasicDBObject.

      Further details below :

      I am trying to do a multiple insert using the camel mongo db component.

      My Pojo representation is :

       Person {
       String firstName;
       String lastName;
       }
      

      I have a processor which constructs a valid List of Person pojo and is a valid json structure. When this list of Person is sent to the mongodb producer , on invocation of createDoInsert the type conversion to BasicDBObject fails. This piece of code below looks to be the problem. Should it have more fall backs / checks in place to attempt the list conversion down further below as it fails on the very first cast itself. Debugging the MongoDbProducer the exchange object being received is a BasicDBList which implements DBObject. This causes the singleInsert flag to remain set at true which fails the insertion below as we get a BasicDBList instead of a BasicDBObject :

         if(singleInsert) {
              BasicDBObject insertObjects = (BasicDBObject)insert;
              dbCol.insertOne(insertObjects);
              exchange1.getIn().setHeader("CamelMongoOid", insertObjects.get("_id"));
          }
      

      The Camel MongoDbProducer code fragment

      private Function<Exchange, Object> createDoInsert() {
          return (exchange1) -> {
              MongoCollection dbCol = this.calculateCollection(exchange1);
              boolean singleInsert = true;
              Object insert = exchange1.getIn().getBody(DBObject.class);
              if(insert == null) {
                  insert = exchange1.getIn().getBody(List.class);
                  if(insert == null) {
                      throw new CamelMongoDbException("MongoDB operation = insert, Body is not conversible to type DBObject nor List<DBObject>");
                  }
      
                  singleInsert = false;
                  insert = this.attemptConvertToList((List)insert, exchange1);
              }
      
              if(singleInsert) {
                  BasicDBObject insertObjects = (BasicDBObject)insert;
                  dbCol.insertOne(insertObjects);
                  exchange1.getIn().setHeader("CamelMongoOid", insertObjects.get("_id"));
              } else {
                  List insertObjects1 = (List)insert;
                  dbCol.insertMany(insertObjects1);
                  ArrayList objectIdentification = new ArrayList(insertObjects1.size());
                  objectIdentification.addAll((Collection)insertObjects1.stream().map((insertObject) -> {
                      return insertObject.get("_id");
                  }).collect(Collectors.toList()));
                  exchange1.getIn().setHeader("CamelMongoOid", objectIdentification);
              }
      
              return insert;
          };
      }
      
      

      My route is as below :

          <route id="uploadFile">
          <from uri="jetty://http://0.0.0.0:9886/test"/>
          <process ref="fileProcessor"/>
          <unmarshal>
              <csv>
      
                  <header>fname</header>
                  <header>lname</header>
      
              </csv>
      
          </unmarshal>
      
          <process ref="mongodbProcessor" />
          <to uri="mongodb:mongoBean?database=axs175&amp;collection=insurance&amp;operation=insert" />
      

      and the MongoDBProcessor constructing the List of Person Pojo

      @Component
      public class MongodbProcessor implements Processor {
      @Override
      public void process(Exchange exchange) throws Exception {
      
          ArrayList<List<String>> personlist = (ArrayList) exchange.getIn().getBody();
          ArrayList<Person> persons = new ArrayList<>();
          for(List<String> records : personlist){
              Person person = new Person();
              person.setFname(records.get(0));
              person.setLname(records.get(1));
              persons.add(person);
          }
      exchange.getIn().setBody(persons);
      
      }
      } 
      
      

      Attachments

        Issue Links

          Activity

            People

              davsclaus Claus Ibsen
              itsavvy.ankur Ankur Saxena
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: