İlkay Gunel
İlkay Gunel

Reputation: 852

Spring CrudRepository Save For Update Overrides Other Fields

I'm using CrudRepository for database operations in my project. When I update an persisted data with save method whis is implemented by Spring, other fields are being overrided. Such as, I'm sending only firstName for updating but lastName is being converted to empty field.

Simply, I'm calling the save method with entity like this:

memberRepository.save(memberForUpdate);

I'm sending this JSON to update method:

{"id":2,"firstName": "Rubens","lastName": "Barichello"}

Spring converts this JSON to Member at the rest api endpoint. Member.java is:

package com.ilkaygunel.entities;

import java.time.LocalDateTime;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;

@Entity
@JsonInclude(Include.NON_NULL)
public class Member {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    private String firstName;
    private String lastName;
    private String email;
    private boolean enabled;
    private String password;
    private String memberLanguageCode;
    private String activationToken;
    private LocalDateTime activationTokenExpDate;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "id")
    private MemberRoles roleOfMember;

    @Override
    public String toString() {
        return String.format("Member [id=%d, firstName='%s', lastName='%s', email='%s']", id, firstName, lastName,
                email);
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public boolean isEnabled() {
        return enabled;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public MemberRoles getRoleOfMember() {
        return roleOfMember;
    }

    public void setRoleOfMember(MemberRoles roleOfMember) {
        this.roleOfMember = roleOfMember;
    }

    public String getActivationToken() {
        return activationToken;
    }

    public void setActivationToken(String activationToken) {
        this.activationToken = activationToken;
    }

    public LocalDateTime getActivationTokenExpDate() {
        return activationTokenExpDate;
    }

    public void setActivationTokenExpDate(LocalDateTime activationTokenExpDate) {
        this.activationTokenExpDate = activationTokenExpDate;
    }

    public String getMemberLanguageCode() {
        return memberLanguageCode;
    }

    public void setMemberLanguageCode(String memberLanguageCode) {
        this.memberLanguageCode = memberLanguageCode;
    }
}

How can I prevent overriding other fields and provide updating only sended fields?

Upvotes: 2

Views: 2429

Answers (1)

Shubham Kadlag
Shubham Kadlag

Reputation: 2308

The save method itself behaves like saveorUpdate, so the problem here is with your code.

What you are doing is only set some values values any not other values. So when you send partial json to spring it sets other values to their default values. Now the problem is here, null is valid value in database. So the CrudRepository is updating the all the values along with null value as it considers you want to update to the database with the values in the object. Consider your scenario here:

Json sent to Spring :{"id":2,"firstName": "Rubens","lastName": "Barichello"}

Object generated by Spring:

private long id=2;
private String firstName="Rubens";
private String lastName="Barichello";
private String email=null;
private boolean enabled=false;
private String password=null;
private String memberLanguageCode=null;
private String activationToken=null;
private LocalDateTime activationTokenExpDate=null;

So what you should do is get the object with findById(ID id) method, set the values and then call the save(S entity) method.

Eg.

memberfromspring;
memberforupdate= memberRepository.findById(memberfromspring.getId());
memberforupdate.setFirstName(memberfromspring.getFirstName());
memberforupdate.setLastName(memberfromspring.getLastName());
memberRepository.save(memberForUpdate);

Upvotes: 4

Related Questions