#java #spring #spring-boot #spring-data #spring-data-neo4j
#java #spring #spring-boot #spring-данные #spring-data-neo4j
Вопрос:
Чтобы исключить некоторые поля объекта, я создал проекцию интерфейса, которая возвращает только некоторые из полей.
Я хотел добавить метод в интерфейс репозитория (который расширяет Neo4jRepository), который использует пользовательский запрос, написанный в Cypher (с использованием аннотации @Query)
Этот метод работает, если я устанавливаю возвращаемому объекту значение Entity, но он возвращается null
, когда возвращаемому объекту присваивается значение projection. Прогнозы работают с обычными методами репозитория (без пользовательских запросов)
Пример кода: Также — я использую 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, и он работает так, как ожидалось
- Конечно, этот пример тривиален, и обычно мне не нужен пользовательский запрос для этого, но проблема вернется ко мне, когда возникнут более сложные запросы
- Как я уже сказал, метод пользовательского запроса работает, когда я использую entity вместо projection. И при использовании проекции в журнале отладки говорится,
looking for concrete class to resolve label: Person
так что, возможно, это каким-то образом заставляет использовать entity? Просто вещь, о которой я думал - Я использую последнюю версию
spring-boot-starter-data-neo4j
Есть ли способ это исправить? Как я мог это сделать? И если исправление невозможно, каким другим способом я мог бы подойти к этой проблеме?
Комментарии:
1. Вы пытались аннотировать PersonProjection с помощью @QueryResult (org.springframework.data.neo4j.annotation. Результат запроса)
2. Я так и сделал. Он возвращает объект JSON с соответствующими полями, но они все
null
. Я также получаю предупреждение, но я не могу сказать, актуально ли это:QueryResult interface method toString doesn't appear to be a getter and therefore may not return the correct result.
Ответ №1:
- Вам нужен @QueryResult в вашем интерфейсе
- Используемый вами запрос не будет работать с SDN (spring data neo4j), он нуждается в небольшой модификации при возврате результата, как показано ниже @Query(«СОПОСТАВЬТЕ (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();
}