Spring Repository method complains about field not found

315 Views Asked by At

I'm using Spring Data Neo4j in my project and I'm having issues with naming conventions for repositories.

This is a simple class containing only one field and the getters/setters

@RelationshipEntity
public class ScoredRelationship
{
  protected Float score;
}

and the class below extends it with other kind of fields

@RelationshipEntity(
    type = RecommenderRelTypes.GOV_CONSUMER_TO_GOV_CONSUMER_SIMILARITY)
public class GovConsumerToGovConsumerSimilarity extends ScoredRelationship
{ // Other fields}

To access the relationship, I'm using the usual repository class

public interface GovConsumerToGovConsumerSimilarityRepository extends
    GraphRepository<GovConsumerToGovConsumerSimilarity>
{

  public Set<GovConsumerToGovConsumerSimilarity> findByScoreGreaterThan(Float value);

  public Set<GovConsumerToGovConsumerSimilarity>
     findByScoreGreaterThanOrderByScoreDesc(Float value);

  public Set<GovConsumerToGovConsumerSimilarity>
     findTopXByScoreGreaterThanOrderByScoreDesc(int limit, Float score);
}

This code compiles well. However, whenever I'm trying to use one of the methods, Spring return a series of exception or doesn't act as intended.

F.e. #findByScoreGreaterThan(0.3f) always returns an empty set. However, invoking a findAll() and printing all the scores it actually has a lot of objects with a score greater than 0.3.

In the second and third case, it always throws an exception saying

Caused by: Unknown identifier `score`.
    at org.neo4j.cypher.internal.symbols.SymbolTable.evaluateType(SymbolTable.scala:60)
    at org.neo4j.cypher.internal.commands.expressions.Identifier.evaluateType(Identifier.scala:51)
    at org.neo4j.cypher.internal.commands.expressions.Expression.assertTypes(Expression.scala:53)
    at org.neo4j.cypher.internal.pipes.SortPipe$$anonfun$assertTypes$1.apply(SortPipe.scala:34)
    at org.neo4j.cypher.internal.pipes.SortPipe$$anonfun$assertTypes$1.apply(SortPipe.scala:33)
    at scala.collection.LinearSeqOptimized$class.foreach(LinearSeqOptimized.scala:59)
    at scala.collection.immutable.List.foreach(List.scala:45)
    at org.neo4j.cypher.internal.pipes.SortPipe.assertTypes(SortPipe.scala:33)
    at org.neo4j.cypher.internal.pipes.PipeWithSource.<init>(PipeWithSource.scala:27)
    at org.neo4j.cypher.internal.pipes.SortPipe.<init>(SortPipe.scala:29)
    at org.neo4j.cypher.internal.executionplan.builders.SortBuilder.apply(SortBuilder.scala:33)
    at org.neo4j.cypher.internal.executionplan.ExecutionPlanImpl.prepareExecutionPlan(ExecutionPlanImpl.scala:49)
    at org.neo4j.cypher.internal.executionplan.ExecutionPlanImpl.<init>(ExecutionPlanImpl.scala:33)
    at org.neo4j.cypher.ExecutionEngine$$anonfun$prepare$1.apply(ExecutionEngine.scala:67)
    at org.neo4j.cypher.ExecutionEngine$$anonfun$prepare$1.apply(ExecutionEngine.scala:67)
    at org.neo4j.cypher.internal.LRUCache.getOrElseUpdate(LRUCache.scala:37)
    at org.neo4j.cypher.ExecutionEngine.prepare(ExecutionEngine.scala:67)
    at org.neo4j.cypher.ExecutionEngine.execute(ExecutionEngine.scala:59)
    at org.neo4j.cypher.ExecutionEngine.execute(ExecutionEngine.scala:63)
    at org.neo4j.cypher.javacompat.ExecutionEngine.execute(ExecutionEngine.java:79)
    at org.springframework.data.neo4j.support.query.CypherQueryEngine.parseAndExecuteQuery(CypherQueryEngine.java:61)

How could be possible? I mean, the class obviously has the score field. Also, executing the simple #findByScoreGreaterThan(float value) doesn't throw any exception, but at the same the latter method always returns an empty set.

EDIT: These are the queries used by Spring. Actually, they seems right

Executing cypher query: START `govConsumerToGovConsumerSimilarity`=node:__types__(className="it.cerict.recommender.persistence.neo4j.GovConsumerToGovConsumerSimilarity") WHERE `govConsumerToGovConsumerSimilarity`.`score`! > {0} RETURN `govConsumerToGovConsumerSimilarity` params {0=0.3}

Executing cypher query: START `govConsumerToGovConsumerSimilarity`=node:__types__(className="it.cerict.recommender.persistence.neo4j.GovConsumerToGovConsumerSimilarity") WHERE `govConsumerToGovConsumerSimilarity`.`score`! > {0} RETURN `govConsumerToGovConsumerSimilarity` ORDER BY score DESC params {0=0.3}

EDIT2: I've also tried to change the score type from Float to float with no further improvements.

1

There are 1 best solutions below

0
On

This seems to be a bug related to Spring Data Neo4j. Looking to the query executed, it is clear that it searches for nodes, while it should search for relationships.

I changed the #findByScoreGreaterThanOrderByScoreDesc() method using the @Query annotation that specifies the following Cypher query

START `govConsumerToGovConsumerSimilarity`=rel:__rel_types__(className="it.cerict.recommender.persistence.neo4j.GovConsumerToGovConsumerSimilarity") WHERE `govConsumerToGovConsumerSimilarity`.`score`! > 0.3 RETURN `govConsumerToGovConsumerSimilarity` ORDER BY `govConsumerToGovConsumerSimilarity`.`score` DESC;