Background
My spring data neo4j application is giving out cypher errors.
This is odd because I am using neo ogm to manage all of my cyper statements, I have not written any cypher myself.
Here are my errors:
Cypher Error in CLI output
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 ']...
OGM error in CLI output after the cypher error
...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, '...
Error locating the spot in my code where the error originates (GenericService)
...myproject.service.GenericService.find(GenericService.java:39) ~[classes/:na]...
Line 39 of GenericService
Optional<T> object = getRepository().findById(id, depth);
Where I'm stuck
findById
is declared in the springframework.data.neo4j.repository.Neo4jRepository.java as Optional<T> findById(ID id, int depth);
I have recently started using neo4jrepository instead of graphrepository since I switched to the Spring data neo4j 5.0.0.
So, I think I have located the issue in the code, but its not my code, its the library, but I cant' believe that a the most recent neo4j ogm was released with a bug in the findById
function.
Question
How do I get past this Cypher Error? Where could this problem be originating from?
UPDATE 1
I am using neo4j-ogm-version 3.0.0, spring-boot 2.0.0.M3, Neo4J is 3.2.3 and spring-data-neo4j 5.0.0.RELEASE,
UPDATE 2
Could it be that my id is instantiated as a Long
whereas Neo4jRepository.java has is instantiated as an ID
?
MORE CONTEXT in GenericService.java
public T find(Long id) {
Optional<T> object = getRepository().findById(id, DEPTH_ENTITY);
if(object.isPresent())
return object.get();
return null;
}
UPDATE 3
springframework.data.neo4j.repository.Neo4jRepository.java contains
@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);
}
Looks like you are not very familiar with Java and its generics type.
Let's take it step by step :
You need to define an entity, for example
@NodeEntity
public class User {
@Id @GeneratedValue
private Long id;
...
Then define a repository extending Neo4jRepository from SDN
public interface UserRepository extends Neo4jRepository<User, Long> {
}
This way you specialize Neo4jRepository
by indicating you want a repository to manage User
whose identity is defined by a Long
.
The method defined in Neo4jRepository
:
Optional<T> findById(ID id, int depth);
Becomes this specialized version in your repository
Optional<User> findById(Long id, int depth);
You never use Neo4jRepository
directly, only the sub-interfaces you define.
For much more details please check the Spring Data commons reference. Also consider having a look at java generic types.
Update
Besides the fact the use of SDN is incorrect, I think the cause of the error is that you use a Neo4j version < 3.1
I highly doubt you are using 3.2.3 as specified in your comment. Please double check.