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 theobjectToUpdate
. SeemsreaderForUpdating
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!!