2015-12-24 3 views
2

Я замечаю, что когда наследование используется в модели данных spring-data-neo4j 4, суперкласс используется в качестве дискриминатора при загрузке и распознавании отношений на основе типа конечного узла. Есть ли способ заставить Spring-data-neo4j-4 использовать подкласс как дискриминатор вместо этого?Neo4j - Дискриминационные отношения на основе типа подкласса конечного узла

Например, у нас есть модель данных (диаграмма классов), как показано слева и ее представление базы данных neo4j справа.

Class diagram and neo4j representation

В настоящее время, если у нас есть Владелец объект с кодом по линиям:

@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 

    ... 
} 

Пружинных данные Neo4j-4 рамки автоматически сопоставляет как собаку и кошку в набор из кошек и набора собак, поэтому у меня есть две «собаки» (хотя один из них на самом деле кот) и две «кошки» (хотя одна из них на самом деле является собакой), загружаемой из базы данных. Если я удалю суперклассы Pet и BaseNodeEntity из модели данных, то Dog и Cat автоматически сопоставляются с их соответствующими наборами правильно.

Есть ли способ, которым я могу заставить spring-data-neo4j-4 правильно отобразить мою модель данных, или я буду вынужден изменить мою модель данных? Я не хочу удалять суперклассы из моей модели данных, так как у меня много повторного использования, и добавление дополнительных отношений (т. Е. Разделение OWNS на CAT_OWNER и DOG_OWNER) было бы так же раздражающим.

Update

Я теперь заметил это поведение не согласуется. Я написал блок-тесты, которые тестируют сопоставления. Странно, иногда он проходит, а иногда и не получается (иногда он ошибочно отображает кошку как собаку, а собаку - как кошку, а иногда и нет). Ручное тестирование блока 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?

Update 8 мая 2016

К сожалению о задержке в обновлении этого. У меня только была возможность снова начать работу над этим проектом. Я проверил это и получаю те же результаты с последней стабильной версией 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(); 
    } 

Возвращает объект Члена, который имеет Набор createdTags, содержащий 2 метки и тег, который фактически является событием.

Моя текущая модель предметной области ниже (не упрощена для собак и кошек):

OGM Diagram

Дополнительная информация:

Я попытался аннотирования все объекты модели, кроме BaseNodeEntity с @NodeEntity аннотация. Свойства аннотируются.

Update 9 мая 2016

я получаю те же неустойчивые результаты, если я поменять код OGM для loadMemberByEmailAddressPasswordAccount с полученным искателе в репозитории.

+0

Спасибо за код , Я посмотрю – Luanne

+0

Я открыл https://github.com/neo4j/neo4j-ogm/issues/161 – Luanne

+0

Спасибо, и спасибо за ваш код. Ты удивительный! :) –

ответ

1

Дела, над которой участвует коллекции отношений с тем же типом, но различными типами конечных узлов были bug- http://github.com/neo4j/neo4j-ogm/issues/161

Это было исправлено и доступно в Neo4j OGM 2.0.2

+0

Спасибо Luanne! Включили новый выпуск в нашу последнюю сборку, и наши внутренние тесты для этого все проходят сейчас :) –