简体   繁体   English

保存新关系时关系变得疏离

[英]Relatioships getting detached when saving new ones

Good morning, I am using SDN-RX which I am adding through spring-data-neo4j-rx-spring-boot-starter version 1.0.0-beta04 and my neo4j database is version 4.0.2 enterprise version.早上好,我正在使用我通过 spring-data-neo4j-rx-spring-boot-starter 版本 1.0.0-beta04 添加的 SDN-RX,我的 neo4j 数据库是版本 4.0.2 企业版。 I have a ClassificationDomain node type and have defined a regionClassificationDomain of type ClassificationDomain to which i have attached a "Continent" node of type RegionType, the continent node is the root node of a hierarchical structure of more region types as follows:我有一个 ClassificationDomain 节点类型,并定义了一个 ClassificationDomain 类型的 regionClassificationDomain,我附加了一个 RegionType 类型的“大陆”节点,大陆节点是更多区域类型的层次结构的根节点,如下所示:

"continent"->"country"->"state/province" etc.....

I am now defining actual region nodes which are also hierarchical and need to be attached to their corresponding region types as follows我现在正在定义实际的区域节点,这些节点也是分层的,需要附加到它们相应的区域类型,如下所示

"africa" -> "zimbabwe" -> "harare" etc

My problem is that when I save a new region node, say I want to attach a child region to "Harare", a lot of other relationships are getting detached on the regionType hierarchy as well as on the region hierarchy.我的问题是,当我保存一个新的区域节点时,比如说我想将一个子区域附加到“Harare”,许多其他关系在 regionType 层次结构以及区域层次结构上都分离了。

“非洲”与 RegionType 分离

What am I missing or doing wrong?我错过了什么或做错了什么?

My Repositories are extending ReactiveNeo4jRepository.我的存储库正在扩展 ReactiveNeo4jRepository。

The Region POJO地区 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;
        }
    }

My Classification POJO我的分类 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;

    }

The Region controller, I have left out the imports. controller 区域,我省略了进口。


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

Thanks in advance for your help.在此先感谢您的帮助。

New answer新答案

The region you are providing in the rest controller method seems not to contain the whole graph that should get persisted in the this.service.getRepository().save(region) call.您在 rest controller 方法中提供的region似乎不包含应该在this.service.getRepository().save(region)调用中保留的整个图。 As described in the old answer (and the documentation link), SDN-RX will update the whole graph reachable from the region you want to store.如旧答案(和文档链接)中所述,SDN-RX 将更新从您要存储的region可访问的整个图形。 This includes also other regions that are connected via the parent region(s).这还包括通过父区域连接的其他区域。

One solution would be to solve this adding via a custom Cypher statement (because you just want to add two (?) relationships. The other solution would be to reconstruct your idea to be more Domain Driven Design and you would work from a parent region without the "back references" from a region to its parent.一种解决方案是通过自定义 Cypher 语句解决此添加问题(因为您只想添加两个(?)关系。另一种解决方案是将您的想法重构为更多域驱动设计,并且您可以在没有父区域的情况下工作从区域到其父区域的“反向引用”。

Old answer (may still help others with a similar problem):旧答案(可能仍会帮助其他有类似问题的人):

It seems that you are not fetching the related nodes of the entity you want to persist upfront.您似乎没有获取要预先保留的实体的相关节点。 The moment you persist the data, Spring Data Neo4j RX stores the Java model as it is in the graph.保存数据的那一刻,Spring 数据 Neo4j RX 将 Java Z20F35E630DAF53498DFA4C3F 存储在图中。 This means that it has to know about all relationships it needs to store for the given entity.这意味着它必须知道它需要为给定实体存储的所有关系。

Since it is not clear from your example, I can only guess that your are loading a Continent or a Region only partial with custom Cypher.由于从您的示例中不清楚,我只能猜测您正在使用自定义 Cypher 加载仅部分的ContinentRegion This leads to a sub-graph representation in your application.这会导致您的应用程序中出现子图表示。 For SDN-RX this is the "truth" that needs to get persisted.对于 SDN-RX,这是需要坚持的“真相”。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM