Upsert Mongo Document using spring data mongo

12,548

Unfortunately its the behavior in MongoDB, you can verify the same using shell. So to update create an Update Object and using

Query query = new Query(Criteria.where("id").is(ID)); 

Here ID is the document which you want to update.Based on your requirement set upsert after that using findAndModify update document.

mongoTemplate.findAndModify(query, update,
                new FindAndModifyOptions().returnNew(true).upsert(false),
                someclass.class);
Share:
12,548
Dinkar Thakur
Author by

Dinkar Thakur

I'm software developer at Wiziq, work mainly on .net though not like it much. I love to work on Ruby on Rails, java, python and php.Planning to do Ph.D in computer sciences. Love to ask question and tell answers. Not that much of open source project to name. But working on a project will tell when its basic structure will be ready.

Updated on June 19, 2022

Comments

  • Dinkar Thakur
    Dinkar Thakur almost 2 years

    I have a Class

    @Document
    public class MyDocument {
       @Id
       private String id;
       private String title;
       private String description;
       private String tagLine;
    
       @CreatedDate
       private Date createdDate;
    
       @LastModifiedDate
       private Date updatedDate;
    
       public String getId() {
         return id;
       }
       public void setId(String id) {
         this.id = id;
       }
    
       public String getTitle() {
         return title;
       }
    
       public void setTitle(String title) {
         this.title = title;
       }
    
       public String getDescription() {
         return description;
       }
    
      public void setDescription(String description) {
        this.description = description;
      }
      public String getTagLine() {
         return tagLine;
       }
    
      public void setTagLine(String tagLine) {
        this.tagLine = tagLine;
      }
    }
    

    i have added annotated application with @EnableMongoAuditing

    i have created interface which implements mongorepository

    public interface MyDocumentRepository extends MongoRepository<MyDocument, String> { }

    when i have created RestController with GET,POST,PATCH methods in POST I'm sending {'title':'first'}

    Controller Class POST method is

    @RequestMapping(value = "/", method = RequestMethod.POST)
    public ResponseEntity<?> saveMyDocument(@RequestBody MyDocument myDocument) { 
       MyDocument doc = myDocumentRepo.save(myDocument);
       return new ResponseEntity<MyDocument>(doc, HttpStatus.CREATED);
    }
    

    Its saving the data in mongo.

    {
        "_id" : ObjectId("56b3451f0364b03f3098f101"),
        "_class" : "com.wiziq.service.course.model.MyDocument",
        "title" : "test"
    }
    

    and PATCH request is like

    @RequestMapping(value = "/{id}", method = RequestMethod.PATCH)
    public ResponseEntity<MyDocument> updateCourse(@PathVariable(value = "id") String id,
            @RequestBody MyDocument myDocument) {
        myDocument.setId(id);
        MyDocument doc = courseService.save(myDocument);
        return ResponseEntity.ok(course);
    }
    

    when in make PATCH request with data {"description":"This is test"} it update the docuent BUT it removes title field and createdDate form the document, its doing update which is ok. But i wanted to do an upsert, i can do its using mongoTemplate, but there i have to set each property which i want to set.

    Is there any generic way to that if i get a PATCH request i can update only not null properties.. properties which are coming in request

    spring-data-rest seems to do it using @RepositoryRestResource. How can i achieve the same.

    I don't want to code like this Update update = new Update().set("title", myDocument.getTitle()).set("description", myDocument.getdescription());