spring data neo4j rest projection returns null when using SpEL expression on nested object

243 Views Asked by At

Consider the following output is produced:

Case 1: while retrieving the nested object from neo4j using spring data neo4j interface (projection)

{
    "name": "Dhoni",
    "currentLocation": {
        "city": {
            "name": "qwerqwer",
            "regionalState": {
                "state": {
                    "name": "zxvcxzcvc"
                }
            }
        }
    }
}

Projection Interface:

public interface PersonProjection {//Root
    String getName();
    CurrentLocationProjection getCurrentLocation();
    
    public interface CurrentLocationProjection { // has relationship Props

        CityProjection getCity(); // target object in entity mapping

        interface CityProjection {

            String getName();
            
            RegionalStateProjection getRegionalState();

            interface RegionalStateProjection { // has relationship Props

                StateProjection getState(); // target object in entity mapping

                interface StateProjection {

                    String getName();
                    
                }
            }
        }
    }
}

Case 2: When i tried to get the nested values mapped to 1st level using SpEL, works fine as u can see below

 public interface PersonProjection {//Root
    String getName();
    CurrentLocationProjection getCurrentLocation();
    
    public interface CurrentLocationProjection {

        @Value("#{target.city.name}")
        String getCityName();

        @Value("#{target.city.regionalState.state.name}")
        String getStateName();

    }
}

gives output as:

{
    "name": "Deva",
    "currentLocation": {
        "cityName": "qwerqwer",
        "stateName": "zxvcxzcvc"
    }
}

Case 3: Issue: However, when i try to get nested values mapped to (root level / root node) itself using SpEL via @Value as below:

public interface PersonProjection {
    String getName();

    @Value("#{target.currentLocation.city.name}")
    String getCityName();

    @Value("#{target.currentLocation.city.regionalState.name}")
    String getStateName();
}

expected output:

{
    "name": "Dhoni",
    "cityName": "qwerqwer",
    "stateName": "zxvcxzcvc"
}

But, it throws the following error stating currentLocation is null as below: (but it has value)

WARN 13600 --- [nio-8080-exec-6] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: EL1007E: Property or field 'city' cannot be found on null; nested exception is com.fasterxml.jackson.databind.JsonMappingException: EL1007E: Property or field 'city' cannot be found on null (through reference chain: com.sun.proxy.$Proxy162["currentLocation"])]

I'm bit confused how it works in 1st-level and not in the root level? could someone please point my mistake / guide me to achieve the expected output. Thanks.

Note: SDN (Spring Data Neo4j) version 6.1.2 for ref.

1

There are 1 best solutions below

0
On

There was a bug in Spring Data Neo4j regarding Spring Expression Language using related entities that are not part of the projection. https://github.com/spring-projects/spring-data-neo4j/issues/2325

tl;dr; it is solved in Spring Data Neo4j 6.1.3