MelleD
MelleD

Reputation: 791

Read only properties for POST in spring data rest

Is there a possibility to make some information read only at spring data rest for jpa entities i.e. these are included in the GET, but cannot be set via POST.

Do I have to do it myself?

Example is:

public class Foo{

@Id
private String id;

@ReadOnlyProperty
private int updateCount;

}

Now you can set the updateCount via POST. The field is used internally and also changed internally. It should also be updateable internally. The GET response should include this field, but should not initially be set via POST.

Upvotes: 4

Views: 3790

Answers (2)

MelleD
MelleD

Reputation: 791

The annotation @JsonProperty(access = JsonProperty.Access.READ_ONLY) works.

public class Foo{

    @Id
    private String id;


    @JsonProperty(access = JsonProperty.Access.READ_ONLY) 
    private int updateCount;
    //getter setter

}

Upvotes: 4

yejianfengblue
yejianfengblue

Reputation: 2419

@JsonCreator tells Jackson to use this constructor to instantiate an object. In this example, updateCount is not one of the constructor parameter, so even if the POST or PUT request JSON body contains an property named updateCount, this JSON property updateCount in JSON body is ignored. As you can see in the constructor Foo.updateCount is initialized by code.

A getter getUpdateCount with @JsonProperty make the field updateCount serializable, that is be included in the response body to a GET request.

A setter setUpdateCount with @JsonIgnore make the field updateCount not-deserializable, that is be ignored on a PATCH update request.

I suggest you to remove the setter setUpdateCount, and use method incrementUpdateCount to increment.

public class Foo{

    @Id
    private String id;

    private String name;

    private int updateCount;

    @JsonCreator
    public Foo(@JsonProperty("name") String name) {

        this.name = name;
        this.updateCount = 0;
    }

    // getter and setter of name is omitted for briefness

    @JsonProperty
    public int getUpdateCount() {
        return updateCount;
    }

    @JsonIgnore
    public void setUpdateCount(int updateCount) {
        this.updateCount = updateCount;
    }

    public void incrementUpdateCount(int change) {
        this.updateCount += change;
    }

    public void incrementUpdateCount() {
        this.updateCount += 1;
    }
}

Disable Jackson mapper feature INFER_PROPERTY_MUTATORS, by adding to your application.properties

spring.jackson.mapper.infer-property-mutators = false

or application.yml if you use YAML format

spring:
  jackson:
    mapper:
      infer-property-mutators: false

If Jackson mapper feature INFER_PROPERTY_MUTATORS is enabled, a getter implies a field to be deserialzable. I have a test case to show the difference between enable and disable this feature.

Upvotes: 1

Related Questions