Home > AI > Backend > SpringBoot > mongodb >

The difference between MongoRepository and MongoTemplate

Source: https://stackoverflow.com/questions/17008947/whats-the-difference-between-spring-datas-mongotemplate-and-mongorepository

regarding updates in a multi-threaded environment:

  • MongoTemplate provides “atomic” out-of-the-box operations updateFirstupdateMultifindAndModifyupsert… which allow you to modify a document in a single operation. The Update object used by these methods also allows you to target only the relevant fields.
  • MongoRepository only gives you the basic CRUD operations findinsertsavedelete, which work with POJOs containing all the fields. This forces you to either update the documents in several steps (1. find the document to update, 2. modify the relevant fields from the returned POJO, and then 3. save it), or define your own update queries by hand using @Query.

In a multi-threaded environment, like e.g. a Java back-end with several REST endpoints, single-method updates are the way to go, in order to reduce the chances of two concurrent updates overwriting one another’s changes.

Example: given a document like this: { _id: "ID1", field1: "a string", field2: 10.0 } and two different threads concurrently updating it…

With MongoTemplate it would look somewhat like this:

THREAD_001
|
|update(query("ID1"), Update().set("field1", "another string")
|
THREAD_002
|
|update(query("ID1"), Update().inc("field2", 5))
|

and the final state for the document is always { _id: "ID1", field1: "another string", field2: 15.0 } since each thread is accesing the DB only once and only the specified field is changed.

Whereas the same case scenario with MongoRepository would look like this:

THREAD_001
|
|pojo = findById("ID1")
|pojo.setField1("another string") /* field2 still 10.0 */
|save(pojo)
|
THREAD_002
|
|pojo = findById("ID1")
|pojo.setField2(pojo.getField2()+5) /* field1 still "
|save(pojo)
|

and the final document being either { _id: "ID1", field1: "another string", field2: 10.0 } or { _id: "ID1", field1: "a string", field2: 15.0 } depending on which save operation hits the DB last.
(NOTE: Even if we used Spring Data’s @Version annotation as suggested in the comments, not much would change: one of the save operations would throw an OptimisticLockingFailureException, and the final document would still be one of the above, with only one field updated instead of both.)

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.

Leave a Reply