简体   繁体   English

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

[英]Custom queries don't work with interface projections in Spring Data Neo4j repositories

To exclude some of the entity's fields I created an interface projection which returns only some of the fields.为了排除实体的某些字段,我创建了一个仅返回某些字段的界面投影。

I wanted to add a method in the repository interface (which extends Neo4jRepository ) which uses a custom query written in Cypher (using the @Query annotation)我想在存储库接口(扩展Neo4jRepository )中添加一个方法,该方法使用用 Cypher 编写的自定义查询(使用@Query注释)

This method works if I set the return object to Entity but it returns null when the return object is set to the projection.如果我将返回对象设置为 Entity,则此方法有效,但当返回对象设置为投影时,它返回null Projections work with the normal repository methods (without custom queries)投影与普通的存储库方法一起工作(没有自定义查询)

Example code: Also - I use lombok but I doubt that it makes any difference here示例代码:另外 - 我使用 lombok,但我怀疑它在这里有什么不同

PersonEntity.java 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人物投影.java

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

PersonRepository.java 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
}

Some things to note:一些注意事项:

  1. This cypher query is 100% correct.这个密码查询是 100% 正确的。 Tested it in Neo4j Desktop and it works as expected在 Neo4j Desktop 中对其进行了测试,它按预期工作
  2. Of course this example is trivial and I normally wouldn't need a custom query for that but the problem will get back to me when some more complex queries arise当然,这个例子是微不足道的,我通常不需要自定义查询,但是当出现一些更复杂的查询时,问题会回到我身上
  3. As I said, the custom query method works when I use entity instead of projection.正如我所说,当我使用实体而不是投影时,自定义查询方法有效。 And while using projection, the debug log says looking for concrete class to resolve label: Person so maybe it somehow forces the usage of entity?在使用投影时,调试日志说looking for concrete class to resolve label: Person所以也许它以某种方式强制使用实体? Just a thing I thought about只是我想到的一件事
  4. I'm using the latest version of spring-boot-starter-data-neo4j我正在使用最新版本的spring-boot-starter-data-neo4j

Is there a way to fix it?有办法解决吗? How could I do it?我怎么能做到? And if the fix is not possible, what's the other way I could approach this issue?如果无法修复,我可以解决此问题的另一种方法是什么?

  1. You need @QueryResult on your interface你的界面上需要@QueryResult
  2. The query you use will not work with SDN(spring data neo4j), it needs slight modification while returning the result as below @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")您使用的查询不适用于 SDN(spring data neo4j),返回结果时需要稍作修改 @Query("MATCH (n: Person ) WHERE is_man = true WITH n RETURN ID(n) as id ,n.first_name 作为 firstName,n.is_man 作为 isMan")

Then it will work.然后它会起作用。 Below is the example that works fine下面是工作正常的例子

 @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();

   

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM