Spring Data Neo4j 4 - изменение @Fetch для findAll (int depth) всегда возвращает null

У меня есть 3 класса, есть User, Role и UserRole. Я хочу получить данные UserRole, но всегда возвращаю NULL.

Это класс пользователя.

@NodeEntity
public class User {
    @GraphId
    Long id;

    @NotNull
    private String username;

    @NotNull
    private String password;

    @NotNull
    private String firstName;

    @NotNull
    private String lastName;

    @NotNull
    private String role;

    @NotNull
    private Boolean active;

    @Relationship(type = "HAS_ROLE", direction = Relationship.OUTGOING)
    private Set<UserRole> userRoles;

    public User() {
        super();
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }

    public Boolean getActive() {
        return active;
    }

    public void setActive(Boolean active) {
        this.active = active;
    }

    public Iterable<UserRole> getUserRoles() {
        return userRoles;
    }

    public void setUserRoles(Set<UserRole> userRoles) {
        this.userRoles = userRoles;
    }
}

А это мой ролевой класс

@NodeEntity
public class Role {
    @GraphId
    Long id;

    @NotNull
    String name;

    @Relationship(type = "HAS_ROLE",direction = Relationship.OUTGOING)
    @JsonIgnore
    private Set<UserRole> userRoles;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Set<UserRole> getUserRoles() {
        return userRoles;
    }

    public void setUserRoles(Set<UserRole> userRoles) {
        this.userRoles = userRoles;
    }

    public Role() {
        super();
    }
}

А это мой класс UserRole

@RelationshipEntity(type = "HAS_ROLE")
public class UserRole {
    @GraphId
    Long id;

    @StartNode
    @Relationship(type="HAS_ROLE", direction=Relationship.INCOMING)
    User user;

    @EndNode
    @Relationship(type="HAS_ROLE", direction=Relationship.INCOMING)
    Role role;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public Role getRole() {
        return role;
    }

    public void setRole(Role role) {
        this.role = role;
    }

    public UserRole(User user, Role role) {
        super();
        this.user = user;
        this.role = role;
    }

    public UserRole() {
        super();
    }
}

Я хочу показать все данные пользователя, но результат всегда показывает userRoles NULL. Я использую findAll(1) и findAll(2), но ничем не отличается.

Отличие от SDN 3 в том, что мы добавляем в поле только @Fetch. В SDN 4 нет аннотации @Fetch. Как я могу получить все данные?

ОБНОВЛЕНИЕ!!

Я изменил класс, как ответ Луанны, и изменил класс пользователя следующим образом:

@NodeEntity
public class User {
    @GraphId
    Long id;

    @NotNull
    private String username;

    @NotNull
    private String password;

    @NotNull
    private String firstName;

    @NotNull
    private String lastName;

    @NotNull
    private String role;

    @NotNull
    private Boolean active;

    @Relationship(type = "HAS_ROLE")
    private Set<UserRole> userRoles;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }

    public Boolean getActive() {
        return active;
    }

    public void setActive(Boolean active) {
        this.active = active;
    }

    @Relationship(type = "HAS_ROLE")
    public Set<UserRole> getUserRoles() {
        return userRoles;
    }

    @Relationship(type = "HAS_ROLE")
    public void setUserRoles(Set<UserRole> userRoles) {
        this.userRoles = userRoles;
    }

    public User(){
        super();
    }
}

После сохранения данных и их отображения роли отображаются следующим образом:

[{"id":27,"username":"daviduck123","password":"admin","firstName":"David","lastName":"Vincent","role":"admin","active":null,"roles":{"id":"29","name":"ROLE_ADMIN"}}]

Но после этого я снова пытаюсь показать все данные и снова возвращаюсь к NULL следующим образом:

[{"id":27,"username":"daviduck123","password":"admin","firstName":"David","lastName":"Vincent","role":"admin","active":null,"roles":null}]

Это мой репозиторий https://github.com/daviduck123/neo4j-ogm-infiniteloop


person David Vincent    schedule 07.01.2016    source источник
comment
Пользователь должен иметь ссылку на UserRole, а не на роли напрямую, это может быть проблемой.   -  person Luanne    schedule 07.01.2016
comment
Да, это так. Это работает только после того, как я сохранил данные, а затем вернулся к нулю. Но когда я использую класс UserRole, его бесконечный цикл.   -  person David Vincent    schedule 07.01.2016
comment
Странно, UserRole должна работать. Не могли бы вы обновить свою зависимость neo4j-ogm до версии 1.1.4? Здесь может быть какая-то другая (исправленная) ошибка. Если проблема не устранена, откройте вопрос здесь github.com/neo4j/neo4j-ogm/issues с вашим образцом кода   -  person Luanne    schedule 08.01.2016
comment
Я уже обновил neo4j-ogm до 1.1.4, но все равно не работает. Хорошо, я открою тему там. Надеюсь, я найду какое-нибудь решение. Спасибо   -  person David Vincent    schedule 08.01.2016


Ответы (2)


@RelationshipEntity представляет квалифицированную связь между двумя узлами, поэтому использование @Relationship в нем некорректно.

UserRole должно выглядеть так

@RelationshipEntity(type = "HAS_ROLE")
public class UserRole {
    @GraphId
    Long id;

    @StartNode
    User user;

    @EndNode
    Role role;

Направление отношения в классе Role должно быть ВХОДЯЩИМ, поскольку вы определяете отношение HAS_ROLE от User до Role:

    @Relationship(type = "HAS_ROLE",direction = Relationship.INCOMING)
    @JsonIgnore
    private Set<UserRole> userRoles;

   @Relationship(type = "HAS_ROLE",direction = Relationship.INCOMING)    
   public Set<UserRole> getUserRoles() {
        return userRoles;
    }

   @Relationship(type = "HAS_ROLE",direction = Relationship.INCOMING)   
   public void setUserRoles(Set<UserRole> userRoles) {
        this.userRoles = userRoles;
    }

убедитесь, что методы доступа и мутатора также аннотированы (обязательно, если у вас есть ВХОДЯЩЕЕ отношение).

person Luanne    schedule 07.01.2016
comment
Я изменил класс UserRole таким образом, а также класс ролей, добавил аннотацию в геттер и сеттер, но я все еще получаю NULL userRoles при отображении всех данных пользователя. - person David Vincent; 07.01.2016
comment
Вы уверены, что у вас есть правильные данные в графике? то есть он сохраняется с ожидаемыми метками и отношениями? - person Luanne; 07.01.2016
comment
у меня есть некоторые данные, 3 из них имеют отношения, а другой нет. Я смотрю на график Neo4j, и он показывает узел HAS_ROLE. Изображение графика можно увидеть по адресу i67.tinypic.com/nmiv5k.png. - person David Vincent; 07.01.2016

Думаю, решение Луанны сработает, и мы должны его использовать. Но у меня другая работа. Вы можете использовать @Query в репозитории для настройки запроса. В запросе вы можете вернуть все нужные вам объекты и отразить их в карте.

@Query("match (ac: Address) <-[:at]- (c: Company) <-[:of]- (p: Position) -[:at]-> (a: Address) "
        + "where p.name =~ {0} return p as position, c as company, a as address, ac as companyAddress skip {1} limit {2}")
List<Map<String, Object>> fetchByTitle(String title, int start, int pageSize);

А потом вам нужно установить отношения вручную.

List<Position> positions = new ArrayList<Position>();
    for (Map<String, Object> d : data) {
        Position pos = (Position) d.get("position");
        pos.setCompany((Company) d.get("company"));
        pos.setLocation((Address) d.get("address"));
        pos.getCompany().setAddress((Address) d.get("companyAddress"));
        positions.add(pos);
    }

    return positions;

Плюс в том, что вам не нужно использовать @RelationshipEntity, что мне, как специалисту по SQL, до сих пор не нравится. Минус в том, что это не природное решение.

person Junbang Huang    schedule 15.04.2016