调用spatial.addNode报错:无longitude属性,求排查方案
问题分析与解决方案
问题描述
使用Neo4j 5.25结合Spring Data + Neo4j + Spatial扩展开发应用,已执行以下语句创建点图层:
CALL spatial.addPointLayer('wayPoints');
自定义Repository方法saveWithIndexation,意图创建WayPoint节点并添加到wayPoints索引,但调用时抛出异常:
org.neo4j.driver.exceptions.ClientException: Failed to invoke procedure spatial.addNode: Caused by: org.neo4j.graphdb.NotFoundException: No such property, 'longitude'.
WayPoint模型已定义latitude和longitude属性,Repository自定义查询也指定了这两个属性,却依然报错。
WayPoint模型代码:
@Node("WayPoint") @NoArgsConstructor @AllArgsConstructor @Data public class WayPoint { @Id @GeneratedValue private String id; private String parentId; private WayPointLevel level; private Double latitude; private Double longitude; private List<String> tags; }
Repository代码:
@Repository public interface WayPointRepository extends Neo4jRepository<WayPoint, String> { @Query(value = """ CREATE (w:WayPoint {parentId: $wayPoint.parentId, level:$wayPoint.level, latitude:$wayPoint.latitude, longitude:$wayPoint.longitude, tags: $wayPoint.tags}) WITH w CALL spatial.addNode('wayPoints', w) YIELD node RETURN node """) void saveWithIndexation(@Param("wayPoint") WayPoint wayPoint); }
原因分析
Neo4j Spatial的addPointLayer方法默认要求节点使用lat(纬度)和lon(经度)作为属性名,而你定义的节点属性是latitude和longitude,与图层期望的属性名不匹配。调用spatial.addNode时,扩展会自动去节点上查找默认的lon属性,找不到就抛出该异常。
解决方案
有两种可行的解决方式:
方式一:创建图层时指定自定义属性名
重新执行图层创建语句,通过latProperty和lonProperty参数指定你的自定义属性名:
CALL spatial.addPointLayer('wayPoints', 'latitude', 'longitude');
执行该语句后,原有的模型和Repository代码无需修改,即可正常调用saveWithIndexation方法。
方式二:修改模型与查询的属性名适配默认规则
将WayPoint模型的属性名改为lat和lon,同时更新Repository查询中的属性引用:
修改后的WayPoint模型:
@Node("WayPoint") @NoArgsConstructor @AllArgsConstructor @Data public class WayPoint { @Id @GeneratedValue private String id; private String parentId; private WayPointLevel level; private Double lat; private Double lon; private List<String> tags; }
修改后的Repository查询:
@Repository public interface WayPointRepository extends Neo4jRepository<WayPoint, String> { @Query(value = """ CREATE (w:WayPoint {parentId: $wayPoint.parentId, level:$wayPoint.level, lat:$wayPoint.lat, lon:$wayPoint.lon, tags: $wayPoint.tags}) WITH w CALL spatial.addNode('wayPoints', w) YIELD node RETURN node """) void saveWithIndexation(@Param("wayPoint") WayPoint wayPoint); }
修改完成后,原有的wayPoints图层无需重新创建,即可正常使用。
内容的提问来源于stack exchange,提问作者Игорь Смолка
相关产品推荐
相关产品推荐

