【问题标题】:Custom queries don't work with interface projections in Spring Data Neo4j repositories自定义查询不适用于 Spring Data Neo4j 存储库中的接口投影
【发布时间】:2021-01-01 11:56:09
【问题描述】:

为了排除实体的一些字段,我创建了一个界面投影,它只返回一些字段。

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

如果我将返回对象设置为实体,则此方法有效,但当返回对象设置为投影时,它返回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

有办法解决吗?我怎么能做到?如果无法修复,还有什么方法可以解决这个问题?

【问题讨论】:

  • 您是否尝试使用@QueryResult (org.springframework.data.neo4j.annotation.QueryResult) 注释 PersonProjection
  • 我做到了。它返回带有正确字段的 JSON 对象,但它们都是 null。我也收到了警告,但我不知道它是否相关:QueryResult interface method toString doesn't appear to be a getter and therefore may not return the correct result.

标签: java spring spring-boot spring-data spring-data-neo4j


【解决方案1】:
  1. 你的界面上需要@QueryResult
  2. 您使用的查询不适用于 SDN(spring data neo4j),需要稍作修改,返回结果如下 @Query("MATCH (n:Person) WHERE n.is_man = true WITH n RETURN ID(n) as id,n.first_name as firstName, n.is_man as 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();

   

}

【讨论】:

    猜你喜欢
    • 2016-08-29
    • 1970-01-01
    • 2019-02-26
    • 1970-01-01
    • 2018-12-16
    • 2020-02-13
    • 2018-04-18
    • 1970-01-01
    • 2021-04-13
    相关资源
    最近更新 更多