You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@camel.apache.org by "Claus Ibsen (JIRA)" <ji...@apache.org> on 2017/05/24 08:18:04 UTC

[jira] [Resolved] (CAMEL-10728) Camel MongoDB Multiple Insert issue

     [ https://issues.apache.org/jira/browse/CAMEL-10728?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Claus Ibsen resolved CAMEL-10728.
---------------------------------
    Resolution: Fixed
      Assignee: Claus Ibsen

> Camel MongoDB Multiple Insert issue
> -----------------------------------
>
>                 Key: CAMEL-10728
>                 URL: https://issues.apache.org/jira/browse/CAMEL-10728
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-mongodb
>    Affects Versions: 2.18.1
>            Reporter: Ankur Saxena
>            Assignee: Claus Ibsen
>            Priority: Minor
>             Fix For: 2.20.0
>
>
> 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 :
> {code:java}
>  Person {
>  String firstName;
>  String lastName;
>  }
> {code}
> 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 :
> {code:java}
>    if(singleInsert) {
>         BasicDBObject insertObjects = (BasicDBObject)insert;
>         dbCol.insertOne(insertObjects);
>         exchange1.getIn().setHeader("CamelMongoOid", insertObjects.get("_id"));
>     }
> {code}
> The Camel MongoDbProducer code fragment
> {code:java}
> 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;
>     };
> }
> {code}
> My route is as below :
> {code:xml}
>     <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" />
> {code}
> and the MongoDBProcessor constructing the List of Person Pojo
> {code:java}
> @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);
> }
> } 
> {code}



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)