保存新关系时关系变得分离
Relatioships getting detached when saving new ones
早上好,我正在使用通过 spring-data-neo4j-rx-spring-boot-starter 版本 1.0.0-beta04 和我的 neo4j 数据库添加的 SDN-RX版本是4.0.2企业版。我有一个 ClassificationDomain 节点类型,并定义了一个 ClassificationDomain 类型的 regionClassificationDomain,我附加了一个 RegionType 类型的 "Continent" 节点,continent 节点是更多区域类型的层次结构的根节点,如下所示:
"continent"->"country"->"state/province" etc.....
我现在正在定义实际的区域节点,它们也是分层的,需要附加到它们相应的区域类型,如下所示
"africa" -> "zimbabwe" -> "harare" etc
我的问题是,当我保存一个新的区域节点时,假设我想将一个子区域附加到 "Harare",许多其他关系在 regionType 层次结构和区域上分离层次结构。
我错过了什么或做错了什么?
我的存储库正在扩展 ReactiveNeo4jRepository。
POJO 区域
/**
* Parent relationship to be modeled by IS_PARENT_REGION_OF relationship
*/
package registry.domain.geography;
import framework.domain.BayPrincipal;
import registry.domain.taxonomy.Classification;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.neo4j.springframework.data.core.schema.Node;
import org.neo4j.springframework.data.core.schema.Relationship;
import java.util.ArrayList;
import java.util.Set;
/**
* @author ltmutiwekuziwa
*
*/
@Getter
@Setter
@ToString
@Node("Region")
public class Region extends BayPrincipal {
private int regionNumber;
private String commonName;
private String officialName;
private char[] iso2Code = new char[2];
private char[] iso3Code = new char[3];
private ArrayList<String> boundingCoordinatess;
private boolean isMetropolis = false;
/**
* Parent region maintained as set to allow for changes without losing the historical record. Only one relationship then
* should have an open endDate for the relationship
*/
@Relationship(type="PARENT_REGION", direction= Relationship.Direction.OUTGOING)
private Set<Region> parentRegions;
@Relationship(type = "REGION_CLASSIFICATION", direction = Relationship.Direction.INCOMING)
private Set<Classification> regionClassifications;
public Set<Region> getParentRegions() {
return parentRegions;
}
public void setParentRegions(Set<Region> parentRegions) {
this.parentRegions = parentRegions;
}
public Set<Classification> getRegionClassifications() {
return regionClassifications;
}
public void setRegionClassifications(Set<Classification> regionClassifications) {
this.regionClassifications = regionClassifications;
}
}
我的分类POJO
package registry.domain.taxonomy;
import framework.domain.BayModel;
import lombok.*;
import org.neo4j.springframework.data.core.schema.Node;
import org.neo4j.springframework.data.core.schema.Relationship;
import java.time.LocalDateTime;
@Getter
@Setter
@ToString
@EqualsAndHashCode
@Node("Classification")
public class Classification extends BayModel {
private String classificationName;
private String classificationCode;
private String url;
private LocalDateTime startDate;
private LocalDateTime stopDate;
@Relationship(type = "TAXONOMY_CHILD_CLASSIFICATION", direction=Relationship.Direction.OUTGOING)
private Classification child;
}
区域控制器,我忽略了导入。
@RestController
@RequestMapping(value="/api/v1/region")
public class RegionRestApi extends BayRestApi<Region, RegionRepository, RegionService> {
private final ArrayList<String> noneIds = new ArrayList<String>(Arrays.asList("none","null", "0", ""));
@Autowired
ClassificationService classificationService;
@Autowired
public RegionRestApi(RegionService service) {
super(service);
}
@PostMapping("/attach/{parent}/{classification}")
private Mono<Region> attach(@PathVariable("parent") String parentUuid,
@PathVariable("classification")String classificationUuid,
@RequestBody Region region) {
if(!this.noneIds.contains(parentUuid)) {
region.setParentRegions(new HashSet<Region>(
Arrays.asList(this.service.getRepository().findById(parentUuid).block())));
}
Classification cls = this.classificationService.getRepository()
.findById(classificationUuid).block();
if(cls != null){
region.setRegionClassifications(new HashSet<Classification>(
Arrays.asList(cls)));
}
return this.service.getRepository().save(region);
}
}
在此先感谢您的帮助。
新答案
您在其余控制器方法中提供的 region
似乎不包含应在 this.service.getRepository().save(region)
调用中保留的整个图形。
如旧答案(和文档 link)中所述,SDN-RX 将更新从您要存储的 region
可访问的整个图形。这还包括通过父区域连接的其他区域。
一种解决方案是通过自定义 Cypher 语句来解决此添加问题(因为您只想添加两个 (?) 关系。
另一种解决方案是将您的想法重构为更多领域驱动设计,并且您将从父区域开始工作,而无需 "back references" 从区域到其父区域。
旧答案(可能仍会帮助其他有类似问题的人):
您似乎没有获取要预先保留的实体的相关节点。
在您保存数据的那一刻,Spring Data Neo4j RX 存储 Java 模型,因为它在图中。
这意味着它必须知道它需要为给定实体存储的 所有 关系。
由于您的示例并不清楚,我只能猜测您加载的 Continent
或 Region
仅部分带有自定义 Cypher。
这会导致您的应用程序中出现子图表示。
对于 SDN-RX,这是需要持久化的 "truth"。
可以在此处找到更多详细信息https://neo4j.github.io/sdn-rx/current/#save
早上好,我正在使用通过 spring-data-neo4j-rx-spring-boot-starter 版本 1.0.0-beta04 和我的 neo4j 数据库添加的 SDN-RX版本是4.0.2企业版。我有一个 ClassificationDomain 节点类型,并定义了一个 ClassificationDomain 类型的 regionClassificationDomain,我附加了一个 RegionType 类型的 "Continent" 节点,continent 节点是更多区域类型的层次结构的根节点,如下所示:
"continent"->"country"->"state/province" etc.....
我现在正在定义实际的区域节点,它们也是分层的,需要附加到它们相应的区域类型,如下所示
"africa" -> "zimbabwe" -> "harare" etc
我的问题是,当我保存一个新的区域节点时,假设我想将一个子区域附加到 "Harare",许多其他关系在 regionType 层次结构和区域上分离层次结构。
我错过了什么或做错了什么?
我的存储库正在扩展 ReactiveNeo4jRepository。
POJO 区域
/**
* Parent relationship to be modeled by IS_PARENT_REGION_OF relationship
*/
package registry.domain.geography;
import framework.domain.BayPrincipal;
import registry.domain.taxonomy.Classification;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.neo4j.springframework.data.core.schema.Node;
import org.neo4j.springframework.data.core.schema.Relationship;
import java.util.ArrayList;
import java.util.Set;
/**
* @author ltmutiwekuziwa
*
*/
@Getter
@Setter
@ToString
@Node("Region")
public class Region extends BayPrincipal {
private int regionNumber;
private String commonName;
private String officialName;
private char[] iso2Code = new char[2];
private char[] iso3Code = new char[3];
private ArrayList<String> boundingCoordinatess;
private boolean isMetropolis = false;
/**
* Parent region maintained as set to allow for changes without losing the historical record. Only one relationship then
* should have an open endDate for the relationship
*/
@Relationship(type="PARENT_REGION", direction= Relationship.Direction.OUTGOING)
private Set<Region> parentRegions;
@Relationship(type = "REGION_CLASSIFICATION", direction = Relationship.Direction.INCOMING)
private Set<Classification> regionClassifications;
public Set<Region> getParentRegions() {
return parentRegions;
}
public void setParentRegions(Set<Region> parentRegions) {
this.parentRegions = parentRegions;
}
public Set<Classification> getRegionClassifications() {
return regionClassifications;
}
public void setRegionClassifications(Set<Classification> regionClassifications) {
this.regionClassifications = regionClassifications;
}
}
我的分类POJO
package registry.domain.taxonomy;
import framework.domain.BayModel;
import lombok.*;
import org.neo4j.springframework.data.core.schema.Node;
import org.neo4j.springframework.data.core.schema.Relationship;
import java.time.LocalDateTime;
@Getter
@Setter
@ToString
@EqualsAndHashCode
@Node("Classification")
public class Classification extends BayModel {
private String classificationName;
private String classificationCode;
private String url;
private LocalDateTime startDate;
private LocalDateTime stopDate;
@Relationship(type = "TAXONOMY_CHILD_CLASSIFICATION", direction=Relationship.Direction.OUTGOING)
private Classification child;
}
区域控制器,我忽略了导入。
@RestController
@RequestMapping(value="/api/v1/region")
public class RegionRestApi extends BayRestApi<Region, RegionRepository, RegionService> {
private final ArrayList<String> noneIds = new ArrayList<String>(Arrays.asList("none","null", "0", ""));
@Autowired
ClassificationService classificationService;
@Autowired
public RegionRestApi(RegionService service) {
super(service);
}
@PostMapping("/attach/{parent}/{classification}")
private Mono<Region> attach(@PathVariable("parent") String parentUuid,
@PathVariable("classification")String classificationUuid,
@RequestBody Region region) {
if(!this.noneIds.contains(parentUuid)) {
region.setParentRegions(new HashSet<Region>(
Arrays.asList(this.service.getRepository().findById(parentUuid).block())));
}
Classification cls = this.classificationService.getRepository()
.findById(classificationUuid).block();
if(cls != null){
region.setRegionClassifications(new HashSet<Classification>(
Arrays.asList(cls)));
}
return this.service.getRepository().save(region);
}
}
在此先感谢您的帮助。
新答案
您在其余控制器方法中提供的 region
似乎不包含应在 this.service.getRepository().save(region)
调用中保留的整个图形。
如旧答案(和文档 link)中所述,SDN-RX 将更新从您要存储的 region
可访问的整个图形。这还包括通过父区域连接的其他区域。
一种解决方案是通过自定义 Cypher 语句来解决此添加问题(因为您只想添加两个 (?) 关系。 另一种解决方案是将您的想法重构为更多领域驱动设计,并且您将从父区域开始工作,而无需 "back references" 从区域到其父区域。
旧答案(可能仍会帮助其他有类似问题的人):
您似乎没有获取要预先保留的实体的相关节点。 在您保存数据的那一刻,Spring Data Neo4j RX 存储 Java 模型,因为它在图中。 这意味着它必须知道它需要为给定实体存储的 所有 关系。
由于您的示例并不清楚,我只能猜测您加载的 Continent
或 Region
仅部分带有自定义 Cypher。
这会导致您的应用程序中出现子图表示。
对于 SDN-RX,这是需要持久化的 "truth"。
可以在此处找到更多详细信息https://neo4j.github.io/sdn-rx/current/#save