2016-12-05 71 views
0

我正在学习Neo4j并通过spring-data-neo4j使用它,但我努力使它适合我的需求。JSON to @RelationshipEntity(通过Spring Boot)

基本上我想来表示:

A -[{...relationshipKey}]-> B 

即A包含地图的BS,以及在地图上的每个键由属性relationshipKey表示。我这样做是因为AFAIU Neo4J不可能存储地图。

所以我用@RelationshipEntity这样的:

@Data 
@NodeEntity 
class A { 
    @Relationship(type = "CONTAINS_B") 
    Set<ContainsB> containsB; 
} 

@RelationshipEntity(type = "CONTAINS_B") 
@Data 
class ContainsB { 
    @GraphId Long id; 
    @StartNode A a; 
    @EndNode B b; 
    @Property RelationshipKey relationshipKey; // an enum 
} 

@Data 
@NodeEntity 
class B { 
    // Whatever 
} 

我试图用弹簧启动控制器,而我传递一个JSON保存新图。

控制器:

@PostMapping(value = BASE_PATH + "/create") 
A createA(@RequestBody @NonNull A a) { 
    return ARepository.save(a); 
} 

JSON:

{ 
    "containsB": [{ 
     "relationshipKey": "key1", 
     "b": {"someB": "properties"} 
    },{ 
     "relationshipKey": "key2", 
     "b": {"someB": "different properties"} 
    }] 
} 

然而,当我调用控制器,我得到这个异常:

org.neo4j.ogm.exception.MappingException:关系实体A(...) 不能缺少开始或结束节点

当我调试控制器调用时,a.getContainsB().iterator().next().getA()为空,但a.getContainsB().iterator().next().getB()已实例化并具有正确的属性。

如果我的仓库保存之前做到这一点的话,就好像工作正常,而A和B是正确的关系:

a.getContainsB().iterator().next().setA(new A()) 

有没有办法通过将由Neo4j的正确解释的JSON ?

回答

0

原因你的JSON被定义与两个关系“ContainsB”,这是由在领域模型中一个@RelationshipEntity表示的实例的错误

。但是,JSON中“ContainsB”的定义本身不包含对其包含的引用,所以当创建每个包含B时,它没有引用A

解决方案

有一对夫妇的事情,你可以尝试。

最明显的一个是创建“ContainsB”,而不是实例:

{ 
    "relationshipKey": "key1", 
    "a": { ... }, 
    "b": { ... } 
} 

另一种选择是使用JSON生成器,允许你创建对象引用,并在你的定义内部引用它们。 JSOG格式可以让你做到这一点,并与杰克逊兼容。有关更多详情,请参阅https://github.com/jsog/jsog