我使用 Neo4jClient 进行查询,因为我的源节点和目标节点具有相同的标签。
以下是我如何进行查询
@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();
}
}
当数据库中有匹配项时,该函数可以正常工作。
但是,对于某些业务案例,上述查询不一定有匹配项,这意味着它会根据不同的输入返回空结果。当没有匹配到时,会抛出以下异常
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)
有没有办法在结果映射到实体类之前进行空检查?或者说我怎样才能避免这种情况呢?
谢谢
您可以将映射代码修改为
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);
并检查驱动程序在这种情况下返回的
null
值。
(也在https://github.com/spring-projects/spring-data-neo4j/issues/2821回答了这个问题,但想确保其他有同样问题的人也可以在这里找到答案)