Spring-框架 Neo4jRepository 函数 findById 导致 Cypher 错误

Spring-framework Neo4jRepository function, findById, causes a Cypher Error

背景

我的 spring 数据 neo4j 应用程序出现密码错误。

这很奇怪,因为我使用 neo ogm 来管理我所有的 cyper 语句,我自己没有写任何密码。

这是我的错误:

CLI 输出中的密码错误

Error executing Cypher "Neo.ClientError.Statement.SyntaxError"; Code: Neo.ClientError.Statement.SyntaxError; Description: Invalid input '|': expected whitespace, comment, a relationship pattern, '.', node labels, '[', "=~", IN, STARTS, ENDS, CONTAINS, IS, '^', '*', '/', '%', '+', '-', '=', "<>", "!=", '<', '>', "<=", ">=", AND, XOR, OR, ',' or ']...

密码错误后 CLI 输出中出现 OGM 错误

...nested exception is org.neo4j.ogm.exception.CypherException: Error executing Cypher \"Neo.ClientError.Statement.SyntaxError\"; Code: Neo.ClientError.Statement.SyntaxError; Description: Invalid input '|': expected whitespace, comment, a relationship pattern, '...

在我的代码中定位错误发生的位置时出错 (GenericService)

...myproject.service.GenericService.find(GenericService.java:39) ~[classes/:na]...

GenericService 的第 39 行

Optional<T> object = getRepository().findById(id, depth);

我卡在哪里

findById 在 springframework.data.neo4j.repository.Neo4jRepository.java 中声明为 Optional<T> findById(ID id, int depth);

自从我切换到 Spring 数据 neo4j 5.0.0 后,我最近开始使用 neo4jrepository 而不是 graphrepository。

所以,我想我已经在代码中找到了问题,但它不是我的代码,它是库,但我不敢相信最新的 neo4j ogm 是在 findById函数。

问题

我如何克服这个 Cypher 错误?这个问题可能来自哪里?

更新 1

我正在使用 neo4j-ogm-version 3.0.0,spring-boot 2.0.0.M3,Neo4J 是 3.2.3 和 spring-data-neo4j 5.0.0.RELEASE,

更新 2

会不会是我的 id 被实例化为 Long 而 Neo4jRepository.java 被实例化为 ID

GenericService.java

中的更多上下文
public T find(Long id) {
    Optional<T> object = getRepository().findById(id, DEPTH_ENTITY);
    if(object.isPresent())
            return object.get();
    return null;
}

更新 3

springframework.data.neo4j.repository.Neo4jRepository.java 包含

@NoRepositoryBean
public interface Neo4jRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID> {

    <S extends T> S save(S s, int depth);

    <S extends T> Iterable<S> save(Iterable<S> entities, int depth);

    Optional<T> findById(ID id, int depth);

    Iterable<T> findAll();

    Iterable<T> findAll(int depth);

    Iterable<T> findAll(Sort sort);

    Iterable<T> findAll(Sort sort, int depth);

    Iterable<T> findAllById(Iterable<ID> ids);

    Iterable<T> findAllById(Iterable<ID> ids, int depth);

    Iterable<T> findAllById(Iterable<ID> ids, Sort sort);

    Iterable<T> findAllById(Iterable<ID> ids, Sort sort, int depth);

    /**
     * Returns a {@link Page} of entities meeting the paging restriction provided in the {@code Pageable} object.
     * {@link Page#getTotalPages()} returns an estimation of the total number of pages and should not be relied upon for accuracy.
     *
     * @param pageable
     * @return a page of entities
     */
    Page<T> findAll(Pageable pageable);

    /**
     * Returns a {@link Page} of entities meeting the paging restriction provided in the {@code Pageable} object.
     * {@link Page#getTotalPages()} returns an estimation of the total number of pages and should not be relied upon for accuracy.
     *
     * @param pageable
     * @param depth
     * @return a page of entities
     */
    Page<T> findAll(Pageable pageable, int depth);
}

看来您对 Java 及其泛型类型不是很熟悉。

让我们一步步来:

  1. 你需要定义一个实体,例如

    @NodeEntity
    public class User {
        @Id @GeneratedValue
        private Long id;
        ...
    
  2. 然后定义一个从 SDN 扩展 Neo4jRepository 的存储库

    public interface UserRepository extends Neo4jRepository<User, Long> {
    }
    

通过这种方式,您可以通过指示您希望存储库管理 User 来专门化 Neo4jRepository,其身份由 Long 定义。 Neo4jRepository中定义的方法:

Optional<T> findById(ID id, int depth);

成为您存储库中的这个专用版本

Optional<User> findById(Long id, int depth);

你从不直接使用Neo4jRepository,只使用你定义的子接口。

有关更多详细信息,请查看 Spring Data commons reference。还可以考虑查看 java 泛型类型。

更新

除了SDN的使用不正确之外,我认为错误的原因是您使用的Neo4j版本<3.1

我非常怀疑您使用的是评论中指定的 3.2.3。请仔细检查。