2

I was trying to perform a bulk operation in mongodb using spring mongo operations class.

These are my POJO classes :

@Document(collection = "location_settings_mst")
public class LocationSettingsEntity {
    @Id
    private String id;
    @Field("userId")
    private String userId;
    @Field("location")
    private List<LocationSettingEntity> locationSettings = new LinkedList<>();
    // Getters and Setters
}

public class LocationSettingEntity {
    @Field("name")
    private String name;
    @Field("latitude")
    private double lat;
    @Field("longitude")
    private double lon;
    @Field("geoPoint")
    private String geoPoint;
    // Getters and Setters
}

but, when I try to perform the following bulk operation :

// Here mongo is an object of type org.springframework.data.mongodb.core.MongoOperations
BulkOperations bulkOps = mongo.bulkOps(BulkMode.ORDERED, LocationSettingsEntity.class); 
Query query = new Query();
List<LocationSettingEntity> list = new LinkedList<>(); // this list contains LocationSettingEntity objects
query.addCriteria(Criteria.where("userId").is(userId));
Update update = new Update();
update.pushAll("location", list.toArray());
bulkOps = bulkOps.updateOne(query, update);
bulkOps.execute();

I get the following error :

org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class com.panasonic.persistence.entity.LocationSettingEntity.
    at org.bson.codecs.configuration.CodecCache.getOrThrow(CodecCache.java:46)
    at org.bson.codecs.configuration.ProvidersCodecRegistry.get(ProvidersCodecRegistry.java:63)
    at org.bson.codecs.configuration.ProvidersCodecRegistry.get(ProvidersCodecRegistry.java:37)
    at com.mongodb.DBObjectCodec.writeValue(DBObjectCodec.java:210)
    at com.mongodb.DBObjectCodec.encodeMap(DBObjectCodec.java:220)
    at com.mongodb.DBObjectCodec.writeValue(DBObjectCodec.java:196)
    at com.mongodb.DBObjectCodec.encode(DBObjectCodec.java:128)
    at com.mongodb.DBObjectCodec.encode(DBObjectCodec.java:61)
    at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:63)
    at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:29)
    at com.mongodb.connection.UpdateCommandMessage.writeTheWrites(UpdateCommandMessage.java:84)
    at com.mongodb.connection.UpdateCommandMessage.writeTheWrites(UpdateCommandMessage.java:42)
    at com.mongodb.connection.BaseWriteCommandMessage.encodeMessageBodyWithMetadata(BaseWriteCommandMessage.java:129)
    at com.mongodb.connection.RequestMessage.encodeWithMetadata(RequestMessage.java:160)
    at com.mongodb.connection.WriteCommandProtocol.sendMessage(WriteCommandProtocol.java:212)
    at com.mongodb.connection.WriteCommandProtocol.execute(WriteCommandProtocol.java:101)
    at com.mongodb.connection.UpdateCommandProtocol.execute(UpdateCommandProtocol.java:64)
    at com.mongodb.connection.UpdateCommandProtocol.execute(UpdateCommandProtocol.java:37)
    at com.mongodb.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:159)
    at com.mongodb.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:286)
    at com.mongodb.connection.DefaultServerConnection.updateCommand(DefaultServerConnection.java:140)
    at com.mongodb.operation.MixedBulkWriteOperation$Run$3.executeWriteCommandProtocol(MixedBulkWriteOperation.java:480)
    at com.mongodb.operation.MixedBulkWriteOperation$Run$RunExecutor.execute(MixedBulkWriteOperation.java:646)
    at com.mongodb.operation.MixedBulkWriteOperation$Run.execute(MixedBulkWriteOperation.java:399)
    at com.mongodb.operation.MixedBulkWriteOperation$1.call(MixedBulkWriteOperation.java:179)
    at com.mongodb.operation.MixedBulkWriteOperation$1.call(MixedBulkWriteOperation.java:168)
    at com.mongodb.operation.OperationHelper.withConnectionSource(OperationHelper.java:230)
    at com.mongodb.operation.OperationHelper.withConnection(OperationHelper.java:221)
    at com.mongodb.operation.MixedBulkWriteOperation.execute(MixedBulkWriteOperation.java:168)
    at com.mongodb.operation.MixedBulkWriteOperation.execute(MixedBulkWriteOperation.java:74)
    at com.mongodb.Mongo.execute(Mongo.java:781)
    at com.mongodb.Mongo$2.execute(Mongo.java:764)
    at com.mongodb.DBCollection.executeBulkWriteOperation(DBCollection.java:2195)
    at com.mongodb.BulkWriteOperation.execute(BulkWriteOperation.java:136)
    at org.springframework.data.mongodb.core.DefaultBulkOperations.execute(DefaultBulkOperations.java:266)

I tried to debug and found that com.mongodb library check for Codecs for datatypes and when it doesn't find one, it throws the error. As far as I understand spring mongo operation is capable of handling POJOs.

I don't understand what am I missing. Please help ! ! !

1 Answers1

0

Technically you would write a custom codec here's how. I did that but it did not work i then dived into the Mongo Driver Code and there seems to be a mistake.

Looks like they made a mistake here - com.mongodb.DBCollection#DBCollection(java.lang.String, com.mongodb.DB, com.mongodb.operation.OperationExecutor)

DBObjectCodec getDefaultDBObjectCodec() {
    return new DBObjectCodec(MongoClient.getDefaultCodecRegistry(),
                             DBObjectCodec.getDefaultBsonTypeClassMap(),
                             getObjectFactory());
}

Here they set the collection Codec from the default static codec registry, which therefore will never be able to pick up the custom codecs that people write. there are many ppl on the internet stuck on this problem.

The problem can however be solved by converting the update payload into a DBObject which can be done using a com.mongodb.BasicDBObjectBuilder class and is pretty straighforward. not sure if the performance will be as good as a codec. I am thinking of writing my own DBObject builder which will give me the performance. since the basic one is using json i think.

Update update = new Update();
update.pushAll("location", list.stream().map(BasicDBObjectBuilder.start().add(//key,value pairs).get()).collect(Collectors.toList()).toArray());
bulkOps = bulkOps.updateOne(query, update);
bulkOps.execute();
Community
  • 1
  • 1
Wolf7176
  • 309
  • 4
  • 7