spring-projects / spring-projects/spring-data-rest
@Transient annotation won't deserialize fields on MongoRepository PATCH requests [DATAREST-1524]
@odrotbohm is already working on this.
Since Dec 31, 2020.
- Dominant language
- Java
- Stars
- 958
- Forks
- 568
- PR merge metrics
- No merged PRs in 30d
Description
ProtenusBill opened DATAREST-1524 and commented
I encountered this after upgrading from 2.1.x to 2.2.x. We have a class containing a field with a @Transient annotation - we want to read the field from the client's request but not store it in Mongo.
Here's a nominal example:
MyBean.java
@Document
public class MyBean {
@Id
String id;
String persist;
@Transient
String noPersist;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPersist() {
return persist;
}
public void setPersist(String persist) {
this.persist = persist;
}
public String getNoPersist() {
return noPersist;
}
public void setNoPersist(String noPersist) {
this.noPersist = noPersist;
}
}
MyBeanRepository.java
@RepositoryRestResource(path = "myBeans", collectionResourceRel = "myBean")
public interface MyBeanRepository extends MongoRepository<MyBean, String> {
}
MyBeanController.java
@Component
@RequestMapping("/v1/myBeans/")
public class MyBeanController {
@Autowired
MongoTemplate mongo;
@RequestMapping(method = RequestMethod.PATCH, value = "/modify/{id}")
public void modify(
@PathVariable("id") String id,
@RequestBody EntityModel<MyBean> modifiedResource,
HttpServletResponse response) {
if (mongo.findById(id, MyBean.class) == null) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
} else {
MyBean modified = modifiedResource.getContent();
modified.setId(id);
mongo.save(modified);
response.setStatus(HttpServletResponse.SC_NO_CONTENT);
}
}
}
MyBeanEventListener.java
@Component
public class MyBeanEventListener extends AbstractMongoEventListener<MyBean> {
@Override
public void onBeforeConvert(BeforeConvertEvent<MyBean> event) {
MyBean bean = event.getSource();
System.out.println("Persist is null? " + (bean.getPersist() == null));
System.out.println("No persist is null? " + (bean.getNoPersist() == null));
}
}
Here's the output on the following requests:
Default Create Endpoint
POST http://localhost:3002/services/v1/myBeans
{
"persist": "foo",
"noPersist": "bar"
}
Persist is null? false
No persist is null? false
Default Modify Endpoint
PATCH http://localhost:3002/services/v1/myBeans/5ec6ab4eb2c37203c6d546fe
{
"persist": "foo2",
"noPersist": "bar2"
}
Persist is null? false
No persist is null? true
Custom Modify Controller
PATCH http://localhost:3002/services/v1/myBeans/modify/5ec6ab4eb2c37203c6d546fe
{
"persist": "foo3",
"noPersist": "bar3"
}
Persist is null? false
No persist is null? false
I tried a myriad of combinations of Jackson @JSONX... annotations to no avail. My assumption is that the @Transient annotation should not affect JSON serialization/deserialization so this appears to be a bug
Affects: 3.2.7 (Moore SR7)
Issue Links:
- DATAREST-1383 Backend read-only properties overridden for PATCH requests
2 votes, 6 watchers
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.