Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring MongoRepository is updating or upserting instead of inserting

I'm using a :

org.springframework.data.mongodb.repository.MongoRepository 

I start with an empty DB and create an object with _id = 1234 for example, and set some other String field to hello for example, and then do:

repository.save(object); 

All is well, it saves the document in MondoDB.

I create a NEW object, set the same _id = 1234 but set the other String field to world and then to another save :

repository.save(newObject); 

Results : the save works but updates the original object.

Expected results: This should fail with a DuplicateKeyException as _id is unique and I am using 2 separate objects when doing each save.

Defect in spring or am I doing something wrong ???

like image 584
Marc Avatar asked Mar 13 '15 13:03

Marc


People also ask

How does MongoRepository work?

MongoRepository extends the PagingAndSortingRepository and QueryByExampleExecutor interfaces that further extend the CrudRepository interface. MongoRepository provides all the necessary methods which help to create a CRUD application and it also supports the custom derived query methods.

How do I update a document in MongoRepository?

The MongoRepository provides save() and saveAll() methods to update the entities. If entities are already available in collection in Mongo database, then they will be updated otherwise they will be inserted as new entities. The save() method updates one entity at a time and returns the updated entity.

Which is better MongoTemplate or MongoRepository?

So I'd say that MongoTemplate is a better option, unless you have a very elaborated POJO model or need the custom queries capabilities of MongoRepository for some reason. Good points/examples. However your race condition example and undesired result can be avoided using @Version to prevent that very scenario.

Is MongoRepository a JPA?

JPA is the Java Persistence API, against which you can write your own repositories. MongoRepository is apparently one such repository that is specific to MongoDB.


2 Answers

Save, by definition, is supposed to update an object in the upsert style, update if present and insert if not. Read the save operation documentation on the MongoDb website

The insert operation in mongodb has the behavior you expect, but from the MongoRepository documentation it appears that insert is delegated to save so it won't make any difference. But you can give that a try and see if it works for you. Otherwise you can just do a get before to check if the object exists, since it is an index lookup it will be fast.

Edit: Check your repository version, insert was introduced in version 1.7.

like image 147
tinker Avatar answered Oct 14 '22 08:10

tinker


the application shall update only when you have @Id annotation for one of the field, after long difficulty had found this

@Document(collection="bus") public class Bus {  //  @Indexed(unique=true, direction=IndexDirection.DESCENDING, dropDups=true)     @Id     private String busTitle;      private int totalNoOfSeats;     private int noOfSeatsAvailable;      private String busType;  } 

but somehow I could not use @Indexed(unique=true, direction=IndexDirection.DESCENDING, dropDups=true)

like image 28
Naveen Avatar answered Oct 14 '22 08:10

Naveen