自定义查询不适用于Spring Data Neo4j存储库中的接口投影

问题描述

为排除实体的某些字段,我创建了一个界面投影,该接口投影仅返回某些字段。

我想在存储库界面中添加一个方法(扩展了 Neo4jRepository ),该方法使用用Cypher编写的自定义查询(使用 @Query 批注)

如果我将返回对象设置为Entity,则此方法有效,但是当返回对象设置为投影时,它将返回null。投影可以使用普通的存储库方法(无需自定义查询

示例代码也-我使用lombok,但我怀疑这是否会有所不同

PersonEntity.java

@NodeEntity
@Data
public class Person {
  @Id
  @GeneratedValue
  private Long id;
  @Property("first_name")
  private String firstName;
  @Property("last_name")
  private String lastName;
  @Property("is_man")
  private boolean isMan;

PersonProjection.java

public interface PersonProjection {
  Long getId();
  String getFirstName();
  boolean getIsMan();
}

PersonRepository.java

public interface PersonRepository extends Neo4jRepository<Person,Long> {
  @Query("MATCH (n:`Person`) WHERE n.`is_man` = true WITH n RETURN n")
  List<PersonProjection> findMen(); // doesn't work,returns null

  List<PersonProjection> findAllByIsManTrue(); // works,returns the list of men
}

一些注意事项:

  1. 密码查询是100%正确的。在Neo4j Desktop中对其进行了测试,它可以按预期工作
  2. 这个例子当然很简单,我通常不需要自定义查询,但是当出现一些更复杂的查询时,问题会再次出现在我身上
  3. 正如我所说,自定义查询方法在使用实体而不是投影时有效。在使用投影时,调试日志会显示looking for concrete class to resolve label: Person,所以也许它会以某种方式强制使用实体?只是我想到的一件事
  4. 我正在使用spring-boot-starter-data-neo4j的最新版本

是否有解决方法?我该怎么办?如果无法修复,那么我可以用什么其他方式解决此问题?

解决方法

  1. 您的界面上需要@QueryResult
  2. 您使用的查询不适用于SDN(spring data neo4j),在返回结果时需要稍作修改,如下所示 @Query(“ MATCH(n:Person)在哪里n。is_man = true,n返回ID(n)为id,n.first_name为firstName,n.is_man为isMan”“)

然后它将起作用。下面是可以正常工作的示例

 @QueryResult
public interface PersonProjection {
    String getName();
}
  public interface PersonRepository extends Neo4jRepository<Person,Long> {

   
    @Query("MATCH (pr:Person) return pr.name as name")
    public List<PersonProjection> getPersonWithAllFriends();

   

}