Echo
Echo

Reputation: 3049

MongoDB and upsert issue

I have two models:

1-ResourceVacation:

    @Id
    private String resourceID;
    private List<Vacation> vacationList;

2-Vacation:

@Id
private String id;
private String start;
private String title;

The JSON for the ResourceVacation after I inserted into it:

{ "_id" : "foo", "_class" : "com.test.model.ResourceVacation", "vacationList" : [ { "_id" : "1", "start" : "abc", "title" : "test" } ] }

I need to upsert a vacation;if the resourceId I need is already existed into the ResourceVacation,replace the "vacationList" into the json with the one I have.

ELSE: Insert a new ResourceVacation

    Vacation vacation = new Vacation("a", "a", "a");
    List<Vacation> list = new ArrayList<Vacation>();
    list.add(vacation);

    ResourceVacation resourceVacation = new ResourceVacation("foo", list);
    MongoOperations mongoOperations = mongoConfiguration.getMongoTemplate();
    DBCollection db = mongoOperations.getCollection("resourceVacation");

    BasicDBObject myQuery = new BasicDBObject("_id", resourceVacation.getResourceID());
    BasicDBObject myUpdate = new BasicDBObject("push ", new BasicDBObject("vacationList",
            resourceVacation.getVacationList()));

    db.update(myQuery, myUpdate);

I get the following exception :

java.lang.IllegalArgumentException: can't serialize class com.springway.model.Vacation

Upvotes: 2

Views: 5685

Answers (2)

Asya Kamsky
Asya Kamsky

Reputation: 42362

First, it doesn't look like you are doing an upsert at all. The syntax for that in Java API would have a third argument to db.update set to true.

   db.update(com.mongodb.DBObject, com.mongodb.DBObject, boolean /*upsert */, boolean /* multi */)

You shouldn't be doing a $push either - the semantics of what you say you want to do in mongo shell would be:

db.collection.update( {"resourceVacation":resourceID}, {$set:{"vacationList":[...]}, true)

This says: if resourceVacation having resourceID exists, then make its "vacationList" what I'm giving you. If it doesn't exist then insert this record.

If you were using Java API directly, the equivalent of the above would be sufficient.

Looks like you are using MongoTemplate from Spring. You will need to check what version of it you are using because it didn't use to allow upserts. That issue is marked as resolved though. If you're stuck on the older version, then there is a workaround described here.

If you are on the latest, you should be able to use the newly added upsert method directly, as described here.

Upvotes: 1

breinero
breinero

Reputation: 412

The exception could be caused by a known bug with the updateFirst method. Take a look here.

Upvotes: 0

Related Questions