8

With Spring Data REST and Spring Data Mongo, I want to make a domain field (field username of domain User in my example) insertable when create but un-updatable when update. In other words an equivalent of JPA @Column(insertable = true, updatable = false).

I try a few approach but not work. In my github project, domain class and repository are put in /src/main/java/*/*/User.java and UserRepository.java. The test is put in /src/test/java/*/*UserTest.java.

1. Spring Data annotation @ReadOnlyProperty and @Transient

The field is un-insertable when save to DB. See package readonlyproperty and transient_ in the project.

2. Jackson annotation @JsonProperty(access=READ_ONLY)

The field is un-insertable when create via POST request, because the JSON property is ignored when initiate an object. See package jsonpropertyreadonly in the project.

3. @JsonCreator on constructor and @JsonIgnore on setter

If the un-updatable field username is contained in json body of PUT or PATCH request, and username value changes, username get updated, which is unexpected. See package jsoncreator in the project.

4. Do not write a setter

same as 3. See package nosetter in the project.

5. Toggle on/off feature

spring.jackson.deserialization.fail-on-ignored-properties=false
spring.jackson.deserialization.fail-on-unknown-properties=false
spring.jackson.mapper.infer-property-mutators=false

not help

Spring Data REST PUT and PATCH Internal Implementation

  • PUT: it uses Jackson ObjectMapper.readerFor(Class) to initiate a new object
  • PATCH: it uses Jackson ObjectMapper.readerForUpdating(objectToUpdate).readValue(json), which use setter to update the objectToUpdate. Seems readerForUpdating doesn't see the @JsonIgnore on setter.

The only solution I know is implementing the setter in below way

void setUsername(String usernameToSet) {
    if (null == this.username)
        this.username = usernameToSet;
}

And disable PUT method, only use PATCH to update. See package setterchecknull.

Is there a better way? Thank you very much!!

yejianfengblue
  • 2,089
  • 1
  • 14
  • 18
  • There is a Jackson github [issue](https://github.com/FasterXML/jackson-databind/issues/1401) about ObjectMapper.readerForUpdating(value) to handle ignored property since 2016 but not implemented yet. I'd better wait for the impl and use the setter null check for now. – yejianfengblue Apr 15 '20 at 12:33
  • 1
    I submit an [issue](https://jira.spring.io/browse/DATAMONGO-2514) to Spring Data MongoDB Team to ask whether it's possible to add an annotation which makes a field read-only, the result is not likely. – yejianfengblue Jul 02 '20 at 12:24
  • is this still unsolved? – Joergi Sep 16 '20 at 20:49
  • 2
    @Joergi Not resolved yet. Currently I check null in setter. – yejianfengblue Sep 17 '20 at 04:34

0 Answers0