SDN4 总是返回一个关系,即使 neo4j 有多个关系
SDN4 is always returning one relationship even though neo4j has multiple relationships
我有两个实体 Person 和 Building。两者由两个关系实体"PERSON_HAS_ACCESS"(多人可以访问多个建筑物)和"PERSON_OWNS"(一个建筑物只能由一个人拥有,但一个人可以拥有多个建筑物)相关。我能够坚持每种类型的不止一种关系(具体来说是 2 种),并且也可以在 neo4j 浏览器中看到。但是,当我使用会话 API:
访问 Person 实体时
session.loadAll(klazz, new Filter("uuid", uuid), 1).getAccessRelations.size()
总是返回 1,不管它有多少关系。
我总是只得到一种关系。
这是我的领域模型。我添加了 equals 和哈希码,但问题仍然存在。此外,我尝试过只有一种关系,但问题还是一样。这让我疯狂!!。任何帮助将不胜感激。
@NodeEntity
public class Building {
@GraphId
private Long id;
private String uuid;
@Relationship(type = "PERSON_OWNS", direction = Relationship.INCOMING)
private OwnsBuilding ownsRelation;
@Relationship(type = "PERSON_HAS_ACCESS", direction = Relationship.INCOMING)
private Collection<CanAccess> accessRelations = new HashSet<CanAccess>();
public Collection<CanAccess> getAccessRelations() {
return accessRelations;
}
public Building setAccessRelations(Collection<CanAccess> accessRelations) {
this.accessRelations = accessRelations;
return this;
}
public String getUuid() {
return uuid;
}
public Building setUuid(String uuid) {
this.uuid = uuid;
return this;
}
public OwnsBuilding getOwnsRelation() {
return ownsRelation;
}
public Building setOwnsRelation(OwnsBuilding ownsRelation) {
this.ownsRelation = ownsRelation;
return this;
}
@Override
public boolean equals(Object obj) {
if (obj == null || !(obj instanceof Building)) return false;
if(id == null) return false;
return obj == this || this.id.equals(((Building) obj).id);
}
@Override
public int hashCode() {
return id != null ? id.hashCode() : super.hashCode();
}
}
@NodeEntity
public class Person {
private String uuid;
@GraphId
private Long id;
@Relationship(type = "PERSON_HAS_ACCESS", direction = Relationship.OUTGOING)
private Collection<CanAccess> accessRelations = new HashSet<CanAccess>();
@Relationship(type = "PERSON_OWNS", direction = Relationship.OUTGOING)
private Collection<OwnsBuilding> ownsRelations = new HashSet<OwnsBuilding>();
public Collection<CanAccess> getAccessRelations() {
return accessRelations;
}
public Person setAccessRelations(Collection<CanAccess> accessRelations) {
this.accessRelations = accessRelations;
return this;
}
public String getUuid() {
return uuid;
}
public Person setUuid(String uuid) {
this.uuid = uuid;
return this;
}
public Collection<OwnsBuilding> getOwnsRelations() {
return ownsRelations;
}
public Person setOwnsRelations(Collection<OwnsBuilding> ownsRelations) {
this.ownsRelations = ownsRelations;
return this;
}
@Override
public boolean equals(Object obj) {
if (obj == null || !(obj instanceof Person)) return false;
if (id == null) return false;
return obj == this || this.id.equals(((Person) obj).id);
}
@Override
public int hashCode() {
return id != null ? id.hashCode() : super.hashCode();
}
}
@RelationshipEntity(type = "PERSON_HAS_ACCESS")
public class CanAccess {
@GraphId
private Long id;
@StartNode
private Person person;
public CanAccess(){}
public CanAccess(Person person, Building building) {
this.person = person;
this.building = building;
}
@EndNode
private Building building;
public Person getPerson() {
return person;
}
public CanAccess setPerson(Person person) {
this.person = person;
return this;
}
public Building getBuilding() {
return building;
}
public CanAccess setBuilding(Building building) {
this.building = building;
return this;
}
@Override
public boolean equals(Object obj) {
if (obj == null || !(obj instanceof CanAccess)) return false;
if (id == null) return false;
return obj == this || this.id.equals(((CanAccess) obj).id);
}
@Override
public int hashCode() {
return id != null ? id.hashCode() : super.hashCode();
}
}
@RelationshipEntity(type = "PERSON_OWNS")
public class OwnsBuilding {
@GraphId
private Long id;
public OwnsBuilding() {
}
public OwnsBuilding(Person owner, Building building) {
this.owner = owner;
this.building = building;
}
@StartNode
private Person owner;
@EndNode
private Building building;
public Person getOwner() {
return owner;
}
public OwnsBuilding setOwner(Person owner) {
this.owner = owner;
return this;
}
public Building getBuilding() {
return building;
}
public OwnsBuilding setBuilding(Building building) {
this.building = building;
return this;
}
@Override
public boolean equals(Object obj) {
if (obj == null || !(obj instanceof OwnsBuilding)) return false;
if (id == null) return false;
return obj == this || this.id.equals(((OwnsBuilding) obj).id);
}
@Override
public int hashCode() {
return id != null ? id.hashCode() : super.hashCode();
}
}
请将您的 Collection
更改为 Set
-
@Relationship(type = "PERSON_HAS_ACCESS", direction = Relationship.INCOMING)
private Collection<CanAccess> accessRelations = new HashSet<CanAccess>();
至
@Relationship(type = "PERSON_HAS_ACCESS", direction = Relationship.INCOMING)
private Set<CanAccess> accessRelations = new HashSet<CanAccess>();
OGM 可以创建数组或 Set
,List
,Vector
.
此外,尽管与问题无关,但请确保当您的关系方向是 INCOMING
时,您明确注释任何 properties/accessors/mutators。
在你的情况下:
@Relationship(type = "PERSON_HAS_ACCESS", direction = Relationship.INCOMING)
private Set<CanAccess> accessRelations = new HashSet<CanAccess>();
@Relationship(type = "PERSON_HAS_ACCESS", direction = Relationship.INCOMING)
public Set<CanAccess> getAccessRelations() {...}
@Relationship(type = "PERSON_HAS_ACCESS", direction = Relationship.INCOMING)
public Building setAccessRelations(Set<CanAccess> accessRelations) {...}
另一个是 make sure your object model is navigable 特别是在关系实体的情况下。当你创建关系实体时,记得在参与节点上设置它,例如
public CanAccess(Person person, Building building) {
this.person = person;
this.building = building;
this.person.getAccessRelations().add(this);
this.building.getAccessRelations().add(this);
}
我有两个实体 Person 和 Building。两者由两个关系实体"PERSON_HAS_ACCESS"(多人可以访问多个建筑物)和"PERSON_OWNS"(一个建筑物只能由一个人拥有,但一个人可以拥有多个建筑物)相关。我能够坚持每种类型的不止一种关系(具体来说是 2 种),并且也可以在 neo4j 浏览器中看到。但是,当我使用会话 API:
访问 Person 实体时 session.loadAll(klazz, new Filter("uuid", uuid), 1).getAccessRelations.size()
总是返回 1,不管它有多少关系。
我总是只得到一种关系。
这是我的领域模型。我添加了 equals 和哈希码,但问题仍然存在。此外,我尝试过只有一种关系,但问题还是一样。这让我疯狂!!。任何帮助将不胜感激。
@NodeEntity
public class Building {
@GraphId
private Long id;
private String uuid;
@Relationship(type = "PERSON_OWNS", direction = Relationship.INCOMING)
private OwnsBuilding ownsRelation;
@Relationship(type = "PERSON_HAS_ACCESS", direction = Relationship.INCOMING)
private Collection<CanAccess> accessRelations = new HashSet<CanAccess>();
public Collection<CanAccess> getAccessRelations() {
return accessRelations;
}
public Building setAccessRelations(Collection<CanAccess> accessRelations) {
this.accessRelations = accessRelations;
return this;
}
public String getUuid() {
return uuid;
}
public Building setUuid(String uuid) {
this.uuid = uuid;
return this;
}
public OwnsBuilding getOwnsRelation() {
return ownsRelation;
}
public Building setOwnsRelation(OwnsBuilding ownsRelation) {
this.ownsRelation = ownsRelation;
return this;
}
@Override
public boolean equals(Object obj) {
if (obj == null || !(obj instanceof Building)) return false;
if(id == null) return false;
return obj == this || this.id.equals(((Building) obj).id);
}
@Override
public int hashCode() {
return id != null ? id.hashCode() : super.hashCode();
}
}
@NodeEntity
public class Person {
private String uuid;
@GraphId
private Long id;
@Relationship(type = "PERSON_HAS_ACCESS", direction = Relationship.OUTGOING)
private Collection<CanAccess> accessRelations = new HashSet<CanAccess>();
@Relationship(type = "PERSON_OWNS", direction = Relationship.OUTGOING)
private Collection<OwnsBuilding> ownsRelations = new HashSet<OwnsBuilding>();
public Collection<CanAccess> getAccessRelations() {
return accessRelations;
}
public Person setAccessRelations(Collection<CanAccess> accessRelations) {
this.accessRelations = accessRelations;
return this;
}
public String getUuid() {
return uuid;
}
public Person setUuid(String uuid) {
this.uuid = uuid;
return this;
}
public Collection<OwnsBuilding> getOwnsRelations() {
return ownsRelations;
}
public Person setOwnsRelations(Collection<OwnsBuilding> ownsRelations) {
this.ownsRelations = ownsRelations;
return this;
}
@Override
public boolean equals(Object obj) {
if (obj == null || !(obj instanceof Person)) return false;
if (id == null) return false;
return obj == this || this.id.equals(((Person) obj).id);
}
@Override
public int hashCode() {
return id != null ? id.hashCode() : super.hashCode();
}
}
@RelationshipEntity(type = "PERSON_HAS_ACCESS")
public class CanAccess {
@GraphId
private Long id;
@StartNode
private Person person;
public CanAccess(){}
public CanAccess(Person person, Building building) {
this.person = person;
this.building = building;
}
@EndNode
private Building building;
public Person getPerson() {
return person;
}
public CanAccess setPerson(Person person) {
this.person = person;
return this;
}
public Building getBuilding() {
return building;
}
public CanAccess setBuilding(Building building) {
this.building = building;
return this;
}
@Override
public boolean equals(Object obj) {
if (obj == null || !(obj instanceof CanAccess)) return false;
if (id == null) return false;
return obj == this || this.id.equals(((CanAccess) obj).id);
}
@Override
public int hashCode() {
return id != null ? id.hashCode() : super.hashCode();
}
}
@RelationshipEntity(type = "PERSON_OWNS")
public class OwnsBuilding {
@GraphId
private Long id;
public OwnsBuilding() {
}
public OwnsBuilding(Person owner, Building building) {
this.owner = owner;
this.building = building;
}
@StartNode
private Person owner;
@EndNode
private Building building;
public Person getOwner() {
return owner;
}
public OwnsBuilding setOwner(Person owner) {
this.owner = owner;
return this;
}
public Building getBuilding() {
return building;
}
public OwnsBuilding setBuilding(Building building) {
this.building = building;
return this;
}
@Override
public boolean equals(Object obj) {
if (obj == null || !(obj instanceof OwnsBuilding)) return false;
if (id == null) return false;
return obj == this || this.id.equals(((OwnsBuilding) obj).id);
}
@Override
public int hashCode() {
return id != null ? id.hashCode() : super.hashCode();
}
}
请将您的 Collection
更改为 Set
-
@Relationship(type = "PERSON_HAS_ACCESS", direction = Relationship.INCOMING)
private Collection<CanAccess> accessRelations = new HashSet<CanAccess>();
至
@Relationship(type = "PERSON_HAS_ACCESS", direction = Relationship.INCOMING)
private Set<CanAccess> accessRelations = new HashSet<CanAccess>();
OGM 可以创建数组或 Set
,List
,Vector
.
此外,尽管与问题无关,但请确保当您的关系方向是 INCOMING
时,您明确注释任何 properties/accessors/mutators。
在你的情况下:
@Relationship(type = "PERSON_HAS_ACCESS", direction = Relationship.INCOMING)
private Set<CanAccess> accessRelations = new HashSet<CanAccess>();
@Relationship(type = "PERSON_HAS_ACCESS", direction = Relationship.INCOMING)
public Set<CanAccess> getAccessRelations() {...}
@Relationship(type = "PERSON_HAS_ACCESS", direction = Relationship.INCOMING)
public Building setAccessRelations(Set<CanAccess> accessRelations) {...}
另一个是 make sure your object model is navigable 特别是在关系实体的情况下。当你创建关系实体时,记得在参与节点上设置它,例如
public CanAccess(Person person, Building building) {
this.person = person;
this.building = building;
this.person.getAccessRelations().add(this);
this.building.getAccessRelations().add(this);
}