问题描述
为排除实体的某些字段,我创建了一个界面投影,该接口投影仅返回某些字段。
我想在存储库界面中添加一个方法(扩展了 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
}
一些注意事项:
- 此密码查询是100%正确的。在Neo4j Desktop中对其进行了测试,它可以按预期工作
- 这个例子当然很简单,我通常不需要自定义查询,但是当出现一些更复杂的查询时,问题会再次出现在我身上
- 正如我所说,自定义查询方法在使用实体而不是投影时有效。在使用投影时,调试日志会显示
looking for concrete class to resolve label: Person
,所以也许它会以某种方式强制使用实体?只是我想到的一件事 - 我正在使用
spring-boot-starter-data-neo4j
的最新版本
是否有解决方法?我该怎么办?如果无法修复,那么我可以用什么其他方式解决此问题?
解决方法
- 您的界面上需要@QueryResult
- 您使用的查询不适用于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();
}