【问题标题】:Spring Data Neo4j 4 - @Fetch change to findAll(int depth) always return nullSpring Data Neo4j 4 - @Fetch 更改为 findAll(int depth) 始终返回 null
【发布时间】:2016-01-07 02:12:44
【问题描述】:

我有 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 注释。我如何获取所有数据?

更新!!

我更改了 Luanne answer 之类的类,并像这样修改了 User 类:

@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

【问题讨论】:

  • 用户应该有对 UserRole 的引用,而不是直接引用 Roles,这可能是问题
  • 是的。它只有在我保存数据后才起作用,然后它又恢复为空。但是当我使用 UserRole 类时,它的无限循环。
  • 奇怪,UserRole 应该可以工作。你能把你的 neo4j-ogm 依赖升级到 1.1.4 吗?这里可能还有其他一些(固定的)错误在起作用。如果问题仍然存在,请在github.com/neo4j/neo4j-ogm/issues 使用您的示例代码打开一个问题
  • 我已经将 neo4j-ogm 升级到 1.1.4 但仍然无法正常工作。好的,我会在那里打开问题。希望我能找到一些解决方案。谢谢

标签: spring neo4j fetch spring-data-neo4j-4 neo4j-ogm


【解决方案1】:

@RelationshipEntity 表示两个节点之间的限定关系,所以其中@Relationship 的使用是不正确的。

UserRole 应该是这样的

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

    @StartNode
    User user;

    @EndNode
    Role role;

Role 类中关系的方向应该是 INCOMING,因为您定义了从 UserRoleHAS_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;
    }

确保访问器和修改器方法也被注释(当你有一个 INCOMING 关系时是强制性的)。

【讨论】:

  • 我已经像这样更改了 UserRole 类和 Role 类,在 getter 和 setter 中添加了注释,但是在显示所有用户数据时我仍然得到 NULL userRoles。
  • 您确定图表中的数据正确吗?即它与预期的标签和关系一起保存?
  • 我有一些数据,其中 3 个有关系,另一个没有。我查看 Neo4j 图表,它显示节点“HAS_ROLE”。图的图片可以看i67.tinypic.com/nmiv5k.png
【解决方案2】:

我猜 Luanne 的解决方案会奏效,我们应该使用它。但我还有另一项工作。 您可以在存储库中使用 @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 人,我仍然不习惯。 缺点是这不是自然解决方案。

【讨论】:

    猜你喜欢
    • 2016-04-19
    • 2018-03-01
    • 1970-01-01
    • 2015-01-30
    • 1970-01-01
    • 2019-07-03
    • 1970-01-01
    • 2018-02-12
    • 1970-01-01
    相关资源
    最近更新 更多