Spring data neo4j client throws exception when there's no match in database

88 views Asked by At

I'm using Neo4jClient to do the query since my source and target node have the same label.

Following is how I do the query

@Repository
public class Neo4jClientRepository {
    @Autowired
    private Neo4jMappingContext neo4jMappingContext;

    @Autowired
    private Neo4jClient neo4jClient;

    public Collection<NodePair> findNodesByUniqueIds(List<String> srcUniqueIds, String nodeName) {
        BiFunction<TypeSystem, MapAccessor, Node> mappingFunction = neo4jMappingContext.getRequiredMappingFunctionFor(Node.class);

        return neo4jClient.query(
                        """
                                MATCH (src:Node)
                                WHERE src.uniqueId IN $uniqueIds
                                OPTIONAL MATCH (src:Node)-[*1..2]-(target:Node)
                                WHERE toUpper(target.name) = toUpper($name)
                                RETURN {src: src, target: target} AS nodePair
                                """)
                .bind(srcUniqueIds).to("uniqueIds")
                .bind(nodeName).to("name")
                .fetchAs(NodePair.class)
                .mappedBy((typeSystem, record) -> {
                        MapValue nodePair = (MapValue) record.get("nodePair");
                        var src = mappingFunction.apply(typeSystem, nodePair.get("src"));
                        var target = mappingFunction.apply(typeSystem, nodePair.get("target"));
                    return new NodePair(src, target);
                })
                .all();
    }
}

The function works fine when there's a match in the database.

However, for some business cases, the above query doesn't necessarily have a match, meaning it will return empty results based on different inputs. When there's no match, the following exception will be thrown

org.springframework.dao.InvalidDataAccessApiUsageException: NULL is not iterable; Error code 'N/A'
    at org.springframework.data.neo4j.core.Neo4jPersistenceExceptionTranslator.translateImpl(Neo4jPersistenceExceptionTranslator.java:107)
    at org.springframework.data.neo4j.core.Neo4jPersistenceExceptionTranslator.translateExceptionIfPossible(Neo4jPersistenceExceptionTranslator.java:81)
    at org.springframework.data.neo4j.core.DefaultNeo4jClient.potentiallyConvertRuntimeException(DefaultNeo4jClient.java:230)
    at org.springframework.data.neo4j.core.DefaultNeo4jClient$DefaultRecordFetchSpec.all(DefaultNeo4jClient.java:488)

Is there a way to do a null check before the result being mapped to entity class? Or how could I avoid this kind of situation?

Thanks

1

There are 1 answers

3
meistermeier On

You could modify your mapping code to

MapValue nodePair = (MapValue) record.get("nodePair");
var src = mappingFunction.apply(typeSystem, nodePair.get("src"));
if (!nodePair.get("target").isNull()) {
    var target = mappingFunction.apply(typeSystem, nodePair.get("target"));
    return new NodePair(src, target);
}
return new NodePair(src, null);

and check the null value that the driver returns in this case.

(Also answered this at https://github.com/spring-projects/spring-data-neo4j/issues/2821 but wanted to be sure that the answer can be discovered also here by others having the same problem)