繁体   English   中英

在 Spring Boot 中无法通过 Neo4j 实现 CRUD 操作

[英]Cannot implement CRUD operations through Neo4j in Spring Boot

我在通过 Spring Boot 中的Neo4j查询实现CRUD操作时遇到问题。

我的问题位于CityRepositoryRouteRepositoryShortestPathRepositoryRoute实体。

1 ) 当我调用CityRepositorylistAllgetById方法时,在添加如下所示的路线后,我会得到空的城市名称并列出其路线。

[
    {
        "id": "077d1b16-9a4b-4fb0-947b-52031774d949",
        "name": "London",
        "routes": []
    },
    {
        "id": "077d1b16-9a4b-4fb0-947b-52031774d949",
        "name": null,
        "routes": [
            {
                "id": "6db5dd3f-085a-4d50-b025-4f0bee847fcf",
                "from": "London",
                "destination": "Berlin",
                "departureTime": "9:00",
                "arriveTime": "11:30",
                "duration": 2.5
            }
        ]
    }
]

2) (已编辑)在添加任何城市路线并调用城市的listAll后,我得到了屏幕截图中显示的结果。

在此处输入图像描述 在此处输入图像描述

这是我的项目链接:项目

这是邮递员请求集合: 链接

以下是与我的问题相关的屏幕截图: 链接

如何解决我的问题?

这是我的实体,如下所示的城市和路线。

城市

public class City {

    @Id
    @Property
    private UUID id;

    @Property
    private String name;

    @Relationship(type = "ROUTES", direction = Relationship.Direction.OUTGOING)
    private Set<Route> routes = new HashSet<>();

    public City(String name) {
        this.name = name;
    }
}

路线

public class Route {

    @Id
    @Property
    private UUID id;

    @Property
    private String from;

    @Property
    private String destination;

    @Property
    private String departureTime;

    @Property
    private String arriveTime;

    @Property
    private Double duration;
}

这是我的CityRepository如下所示。

public interface CityRepository extends Neo4jRepository<City,UUID> {

    @Query("MATCH (city:City) OPTIONAL MATCH (city)-[r:ROUTES]->(route:Route) RETURN city, collect(r), collect(route)")
    List<City> listAll();

    @Query("MATCH (city:City {id: $cityId}) OPTIONAL MATCH (city)-[r:ROUTES]->(route:Route) RETURN city, collect(r), collect(route)")
    City getById(UUID cityId);

    @Query("MATCH (city:City {name: $cityName}) RETURN city")
    City getByCityName(String cityName);

    @Query("CREATE (city:City {id: randomUUID(), name: $cityName}) RETURN city")
    City saveCity(String cityName);

    @Query("MATCH (city:City {id: $cityId}) SET city.name = $cityName RETURN city")
    City updateCity(UUID cityId, String cityName);

    @Query("MATCH (city:City {id: $cityId}) DELETE city")
    void deleteCity(UUID cityId);
}

这是我的RouteRepository如下所示。

public interface RouteRepository extends Neo4jRepository<Route,UUID> {

    @Query("MATCH (city:City {id: $cityId})-[:ROUTES]->(route:Route) RETURN route")
    List<Route> listAllByCityId(UUID cityId);

    @Query("MATCH (route:Route {id: $routeId}) RETURN route")
    Route getById(UUID routeId);

    @Query("CREATE (city:City {id: $cityId})-[:ROUTES]->(route:Route {id: randomUUID(), from: $from, destination: $destination, departureTime: $departureTime," +
            "arriveTime: $arriveTime, duration: $duration}) " +
            "RETURN route")
    Route saveRoute(UUID cityId, String from, String destination, String departureTime,
                    String arriveTime, double duration);

    @Query("MATCH (city:City {id: $cityId})-[:ROUTES]->(route:Route {id: $routeId}) " +
            "SET route.from = $from, route.destination = $destination,route.departureTime = $departureTime," +
            "route.arriveTime = $arriveTime, route.duration = $duration RETURN route")
    Route updateRoute(UUID cityId, UUID routeId, String from, String destination,String departureTime,
                      String arriveTime,double duration);

    @Query("MATCH (city:City {id: $cityId})-[r:ROUTES]->(route:Route {id: $routeId}) DELETE r, route")
    void deleteRoute(UUID cityId, UUID routeId);
}

第三次更新:自定义保存查询有问题。 有了CREATE.... ,Neo4j 将始终创建新实体。 与至少一个现有节点创建新关系的最安全方法是在现有节点上进行匹配,然后通过在MERGE语句中的命名引用来使用它。 我更新了我的项目,但这里基本上是解决方案:

@Query("MATCH (city:City {id: $cityId}) " +
       "MERGE (city)-[:ROUTES]->(route:Route {id: randomUUID(), from: $from, destination: $destination, departureTime: $departureTime," +
            "arriveTime: $arriveTime, duration: $duration}) " +
            "RETURN route")
Route saveRoute(UUID cityId, String from, String destination, String departureTime,
                    String arriveTime, double duration);

第二次更新:好的,我更新了项目以包括现在从控制器级别开始的 Web 测试。 请查看并调整它以重现我现在错过的错误。

我无法重现 1 和 4,请查看com.springshortpath.app.ApplicationWebTests#listCitiesWithRoutes / com.springshortpath.app.ApplicationWebTests#listRoutesByCity

对于 2 和 3:查询模式要求(至少)定义一个路由。 如果还想获得没有路线的城市,则必须进行可选匹配。

对于 5:Spring Data Neo4j 的存储库只能将实体定义作为返回类型来处理。 如果要使用Java驱动的类型,请使用SDN的Neo4jClient进行交互。 SDN 文档 / Neo4jClient

更新已编辑的问题:

对于路由的删除:该错误表明必须先删除该关系。 正确的查询应该是MATCH (city:City {id: $cityId})-[r:ROUTES]->(route:Route {id: $routeId}) DELETE r, route

对于无法通过城市UUID查找路线:关系的方向错误,正确的是: MATCH (city:City {id: $cityId})-[:ROUTES]->(route:Route) RETURN route

我无法重现其他问题,但为我在您的存储库的一个分支中理解的内容创建了测试用例: https ://github.com/meistermeier/SpringBootNeo4jShortestPath

旧答案:一般来说,我对id属性与节点的id存在误解。

1 ) 当我调用 saveCity 方法时,添加了 id 值为 0 的值。 我不知道为什么将 id 分配给 0。

您将 id 定义为内部 Neo4j 的。

@Id
@GeneratedValue
private Long id;

因此 SDN 会在保存时将此值分配给 id 字段。 节点的内部 id 将通过 Cypher 查询中的id(node)进行比较/检索。

3 ) 当我调用 getCityById 方法时,我看不到任何结果

因此,查询MATCH (city:City {id: $cityId}) RETURN city不会查找正确的 id 字段,而是查找属性id

2)当我调用 listAll 方法时,所有值都被列出(没有路由值,因为我无法添加路由)

如果您仍然在此处引用CityRepository ,则看不到任何Route ,因为您没有返回它们。 将查询更改为MATCH (city:City)-[r:ROUTES]->(route:Route) RETURN city, collect(r), collect(route) (或添加可选子句来获取路线而不是要求模式),也会将Routes添加到相应的Cities

4 ) 当我调用 updateCity 方法时,我看不到任何结果。

这应该可以按预期工作,但我假设您说“看不到任何结果”是指其他内容。 它应该与方法City getByCityName(String cityName)的结果相同,包括 id 属性更改。

对于其余的问题,我打赌这又是node.id属性与id(node)的问题。 所以基本上你拥有的每个地方(n:City|Route...{id: $id})都应该变成(n:City|Route...) WHERE id(n) = $id

请在下面找到我的回复。

1 ) 当我调用 saveCity 方法时,添加了 id 值为 0 的值。 我不知道为什么将 id 分配给 0。

我的回复:当您尝试添加到 db id 值从零开始时,默认为零。 当您添加第二条记录时,id 值将为 1...类似地,当您添加第三条记录时,id 值将为 2,依此类推。

2)当我调用 listAll 方法时,所有值都被列出(没有路由值,因为我无法添加路由)

我的回复:这是默认行为。

  1. 当我调用 getCityById 方法时,我看不到任何结果 我的回复:你可以使用 getById 或 getId

4)4 ) 当我调用 updateCity 方法时,我看不到任何结果。

5 ) 当我调用 deleteCity 方法时,我看到“城市被删除”,但是当我调用 listAll 方法时,我看到了那个值。 据我所知,删除方法无法使用。

6 ) 当我调用 saveRoute 时,它​​已被添加,但存在 id 问题。 当我调用 listAll of City 方法时,我看不到它的值。

7 ) 当我调用 getRouteById 方法时,我看不到任何结果

8 ) 当我调用 listAll 方法时,我看不到任何结果。

9 ) 当我调用 updateRoute 方法时,我看不到任何结果。

10 ) 当我调用 deleteRoute 方法时,我看到“Route is deleted”,但是当我调用 listAll 方法时,我看不到任何结果。 我不知道它是否被删除。

我的回复:对于 4、5、6、7、8、9,我认为您没有在编程方面做出承诺或节省。 提交操作后,只会保存或更新结果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM