spring-projects / spring-projects/spring-data-rest

NullPointerException on deserializing computed (non-persistent) property [DATAREST-574]

Open
#948 6 comments 0 reactions 1 assignee View on GitHub

@odrotbohm is already working on this.

Since Dec 31, 2020.

type: bug
Dominant language
Java
Stars
958
Forks
568
PR merge metrics
No merged PRs in 30d

Description

Ben Madore opened DATAREST-574 and commented

I have a project like:

@Entity
public class Store {
  @Id
  public Long id;

  @OneToMany 
  @JsonIgnore
  public Set<Hours> hours;
  
   @OneToMany
   @JsonIgnore
   public Set<HourOverrides> overrides;

  public TodaysHours getTodaysHoursComputedValue() {
      TodayHours todaysHours = //computation based on hours and overrides
      return todaysHours;
  }

  public setTodaysHoursComputedValue() {
  //Do nothing, just needed so that jackson has a corresponding setter to call, but value is discarded
  }

I have a separate manual controller that handles ```
/stores/{id}/hours


In DomainObjectReader there is the call to: 		
```java
final MappedProperties properties = getJacksonProperties(entity, mapper);
``` which returns all the properties jackson knows about. Then for each of those it calls:
```java
PersistentProperty<?> persistentProperty = entity.getPersistentProperty(property.getInternalName());

which in the case of this, returns null as this is a COMPUTED value and doesn't map to a persisted entity.

The problem is that even though there IS no persistent property it adds the null to a couple of java propertyToFieldName.put(persistentProperty, property.getName()); fieldNameToProperty.put(property.getName(), persistentProperty);
which are later dereferenced and leads to an NPE.

Caused by: java.lang.NullPointerException
	at org.springframework.data.mapping.model.BeanWrapper.getProperty(BeanWrapper.java:96) ~[spring-data-commons-1.11.0.M1.jar:?]
	at org.springframework.data.rest.webmvc.json.DomainObjectReader.doMerge(DomainObjectReader.java:185) ~[spring-data-rest-webmvc-2.4.0.M1.jar:?]
	at org.springframework.data.rest.webmvc.json.DomainObjectReader.merge(DomainObjectReader.java:136) ~[spring-data-rest-webmvc-2.4.0.M1.jar:?]
	at org.springframework.data.rest.webmvc.json.DomainObjectReader.readPut(DomainObjectReader.java:130) ~[spring-data-rest-webmvc-2.4.0.M1.jar:?]
	at org.springframework.data.rest.webmvc.config.JsonPatchHandler.applyPut(JsonPatchHandler.java:134) ~[spring-data-rest-webmvc-2.4.0.M1.jar:?]

I believe the fix would be on DomainObjectReader.java:237 to add a null check before adding the nulls to those maps.

It seems like you should be able to have computed values in your response and to simply ignore them on the deserialization if the client happens to pass them. I know it's a bit of a hack in jackson to have a getter with an empty setter for computed properties - but this is getting full support in jackson 2.6 (https://github.com/FasterXML/jackson-databind/issues/95) - and i believe it's a valid use case.

Please let me know if you disagree, or if you know of any work arounds.


Affects: 2.4 M1 (Gosling)

Issue Links:

  • DATAREST-575 Insufficient check for the presence of a PersistentProperty in MappedProperties
    ("duplicates")

2 votes, 5 watchers

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.