我注意到,当在SpringData-ne4j4数据模型中使用继承时,在加载和区分基于结束节点类型的关系时,将使用超类作为判别器。我是否可以强迫SpringData-ne4j-4使用子类作为鉴别器呢?
例如,假设左边有一个数据模型(类图),右边是它的neo4j数据库表示。

当前,如果我们有一个所有者实体,其代码类似于:
@NodeEntity
class Owner extends BaseNodeEntity {
...
@Relationship(type="OWNS")
private Set<Dog> dogs; // both dog and cat are mapped here
@Relationship(type="OWNS")
private Set<Cat> cats; // both dog and cat are mapped here
...
}spring ne4j-4框架将自动将狗和猫映射到猫集和狗集,因此我有两只“狗”(尽管其中一只实际上是一只猫)和两只“猫”(尽管其中一只实际上是一只狗)。如果我将超类Pet和BaseNodeEntity从数据模型中删除,那么Dog和Cat将自动映射到它们各自的集合。
是否有一种方法可以强制SpringData-ne4j-4正确映射数据模型,或者我将被迫更改数据模型?我不想从我的数据模型中删除超类,因为我有很多重复使用的情况,并且添加额外的关系(即将所有权分割给CAT_OWNER和DOG_OWNER)也会同样令人讨厌。
更新
我现在注意到这种行为是不一致的。我编写了一个单元测试来测试映射。奇怪的是,有时它会通过,有时它会失败(有时它错误地把猫描绘成一只狗,把狗描绘成一只猫,有时它却没有)。手动运行单元测试10次给出了以下通过/失败的结果。
Run, Result (pass / fail)
1 P
2 F
3 F
4 P
5 F
6 P
7 F
8 F
9 P
10 F当然,映射行为应该是一致的。这可能是SDN-4中的一个bug吗?
更新2016年5月8日
很抱歉延迟了更新。我才刚刚有机会重新开始做这个项目。我对此进行了重新测试,并在最新的稳定neo4j版本中获得了相同的结果。
<neo4j.version>2.3.2</neo4j.version>
<sdn.version>4.1.1.RELEASE</sdn.version>
<java.version>1.8</java.version>
<neo4j-ogm.version>2.0.1</neo4j-ogm.version>
<spring-data-commons.version>1.12.1.RELEASE</spring-data-commons.version>我在下面附加了测试用例中使用的实际域模型。测试用例的细节可以在https://github.com/johndeverall/thescene-spa/issues/142上看到。测试用例代码是:
@Test
public void saveAndLoadTags() {
log.info("Given we have a member with some events");
Member member = createMember();
Event event1 = eventService.createEvent("Event1", member);
Event event2 = eventService.createEvent("Event2", member);
log.info("When I tag my events with some tags");
contentService.tag("Tag1", "", event1, member);
contentService.tag("Tag1", "", event1, member); // should create no new tags or relationships
contentService.tag("Tag2", "", event1, member);
contentService.tag("Tag2", "", event2, member);
log.info("Then my events should be appropriately tagged");
event1 = eventService.loadEventBySceneId(event1.getSceneId());
assertThat(event1.getTags().size(), is(equalTo(2)));
assertThat(event2.getTags().size(), is(equalTo(1)));
log.info("And I should have created two tags total");
Iterator<Tag> iterator = contentService.getAllTags().iterator();
List<Tag> tags = StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.ORDERED), false).collect(Collectors.<Tag> toList());
assertThat(tags.size(), is(equalTo(2)));
log.info("And our member should have created two tags");
member = memberService.loadMemberByEmailAddressPasswordAccount(emailAddress);
// **************************************************************
// member.getCreatedTags().size() more often than not returns 3 causing my test failure!
// **************************************************************
assertThat(member.getCreatedTags().size(), is(equalTo(2)));
}测试用例显示的问题
以下方法:
public Member loadMemberByEmailAddressPasswordAccount(String emailAddress) {
Filter filter = new Filter("email", emailAddress);
Collection<EmailAddressPasswordAccount> emailAddressPasswordAccounts = session.loadAll(EmailAddressPasswordAccount.class, filter, 2);
return emailAddressPasswordAccounts.isEmpty() ? null : emailAddressPasswordAccounts.iterator().next().getMember();
}返回一个成员对象,该对象具有一组包含2个标记的createdTags和一个实际上是事件的标记。
我的实际域模型如下(未简化为狗和猫):

附加信息:
我尝试过用@NodeEntity注释来注释除BaseNodeEntity之外的所有模型对象。属性被注释。
更新2016年5月9日
如果使用存储库中的派生查找程序将ogm代码替换为loadMemberByEmailAddressPasswordAccount,则会得到相同的间歇性结果。
发布于 2015-12-28 03:05:31
上面涉及到具有相同类型但不同终端节点类型的关系集合的情况是一个bug- http://github.com/neo4j/neo4j-ogm/issues/161。
这已被修复,并可在Neo4j OGM 2.0.2中使用。
https://stackoverflow.com/questions/34449961
复制相似问题