1

早上好,我正在使用我通过 spring-data-neo4j-rx-spring-boot-starter 版本 1.0.0-beta04 添加的 SDN-RX,我的 neo4j 数据库是版本 4.0.2 企业版。我有一个 ClassificationDomain 节点类型,并定义了一个 ClassificationDomain 类型的 regionClassificationDomain,我附加了一个 RegionType 类型的“大陆”节点,大陆节点是更多区域类型的层次结构的根节点,如下所示:

"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);
        }
    }

在此先感谢您的帮助。

4

1 回答 1

0

新答案

您在 rest 控制器方法中提供的region似乎不包含应该在this.service.getRepository().save(region)调用中持久化的整个图。如旧答案(和文档链接)中所述,SDN-RX 将更新region您要存储的可访问的整个图形。这还包括通过父区域连接的其他区域。

一种解决方案是通过自定义 Cypher 语句来解决此添加问题(因为您只想添加两个(?)关系。另一种解决方案是将您的想法重构为更多的领域驱动设计,并且您可以在没有父区域的情况下工作从区域到其父区域的“反向引用”。

旧答案(可能仍会帮助其他有类似问题的人):

您似乎没有获取要预先保留的实体的相关节点。在您持久化数据的那一刻,Spring Data Neo4j RX 将 Java 模型原样存储在图中。这意味着它必须知道它需要为给定实体存储的所有关系。

由于您的示例尚不清楚,因此我只能猜测您正在使用自定义 Cypher 加载一个ContinentRegion仅部分。这会导致您的应用程序中出现子图表示。对于 SDN-RX,这是需要坚持的“真相”。

更多细节可以在这里找到https://neo4j.github.io/sdn-rx/current/#save

于 2020-05-14T05:17:29.460 回答