Ankur Saxena created CAMEL-10728:
------------------------------------
Summary: 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
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&collection=insurance&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.4#6332)