Как динамически изменять типы объектов в neo4j-ogm или spring-data-neo4j? - PullRequest
0 голосов
/ 14 мая 2018

Возник вопрос "как динамически добавлять метки к узлам в Neo4j". Есть ли способ динамически изменять типы объектов?

Взять пример:

    @NodeEntity
public class User {

   @Properties(prefix = "custom")
   private Map userProperties;

}

Я вижу из https://neo4j.com/blog/spring-data-neo4j-5-0-release/, что я могу создавать динамические свойства. Могу ли я иметь динамические типы также во время выполнения? Я хочу изменить тип «Пользователь» на «Потребитель» / «Администратор» / «Производитель» динамически при необходимости. Типы сущностей не являются исчерпывающими.

Заранее спасибо! :)

Ответы [ 2 ]

0 голосов
/ 10 сентября 2018

Механизм @Labels великолепен, и для многих случаев использования я бы сказал, что это лучшее решение.

Если вы хотите, чтобы другой класс вернулся из вашего хранилища, тогда действительно требуется гораздо больше работы.

Я делаю это в музыкальном проекте.У меня есть Artist (не абстрактный и полностью пригодный для использования там, где я не знаю, группа это или нет) и Band и SoloArtist от Artist с дополнительными метками:

@NodeEntity
public class Artist {}

@NodeEntity
public class Band extends Artist{}

Что я знаю в расширении собственного репозитория, так это:

interface ArtistRepository<T extends Artist> extends Repository<T, Long>, ArtistRepositoryExt {

    Optional<T> findOneByName(String name);

    // Specifying the relationships is necessary here because the generic queries won't recognize that
    // Band has a relationship to country that _should_ be loaded with default depth of 1.

    @Query("MATCH (n:Artist) WITH n MATCH p=(n)-[*0..1]-(m) RETURN p ORDER BY n.name")
    List<T> findAllOrderedByName();

    @Query("MATCH (n:Artist) WHERE id(n) = $id WITH n MATCH p=(n)-[*0..1]-(m) RETURN p")
    Optional<T> findById(@Param("id") Long id);

    <S extends T> S save(S artist);
}

interface ArtistRepositoryExt {
    Band markAsBand(Artist artist);

    SoloArtist markAsSoloArtist(Artist artist);
}

class ArtistRepositoryExtImpl implements ArtistRepositoryExt {

    private static final String CYPHER_MARK_AS_BAND = String.format(
        "MATCH (n) WHERE id(n) = $id\n" +
            "OPTIONAL MATCH (n) - [f:BORN_IN] -> (:Country)\n" +
            "REMOVE n:%s SET n:%s\n" +
            "DELETE f",
        SoloArtist.class.getSimpleName(),
        Band.class.getSimpleName());
    private static final String CYPHER_MARK_AS_SOLO_ARTIST = String.format(
        "MATCH (n) WHERE id(n) = $id\n" +
            "OPTIONAL MATCH (n) - [f:FOUNDED_IN] -> (:Country)\n" +
            "REMOVE n:%s SET n:%s\n" +
            "DELETE f",
        Band.class.getSimpleName(),
        SoloArtist.class.getSimpleName());

    private final Session session;

    public ArtistRepositoryExtImpl(Session session) {
        this.session = session;
    }

    @Override
    public Band markAsBand(Artist artist) {
        session.query(CYPHER_MARK_AS_BAND, Map.of("id", artist.getId()));
        // Needs to clear the mapping context at this point because this shared session
        // will know the node only as class Artist in this transaction otherwise.
        session.clear();
        return session.load(Band.class, artist.getId());
    }

    @Override
    public SoloArtist markAsSoloArtist(Artist artist) {
        session.query(CYPHER_MARK_AS_SOLO_ARTIST, Map.of("id", artist.getId()));
        // See above
        session.clear();
        return session.load(SoloArtist.class, artist.getId());
    }
}

Хотя это работает аккуратно, я пойму идею усилий в сценарии с более глубокими вложенными классами.Кроме того, вы должны переопределить производные методы поиска, как я делаю, если вы хотите использовать хранилище полиморфным способом.

Я также храню выделенные хранилища.

Если этот вопрос все еще актуален дляВы, дайте мне знать, если работает для вас тоже.Вы найдете весь проект здесь:

https://github.com/michael-simons/bootiful-music

0 голосов
/ 17 мая 2018

В Set<String> имеется аннотация @Labels, которая хранится / управляется в дополнение к основному типу из класса и интерфейсов.

см .: https://docs.spring.io/spring-data/neo4j/docs/current/reference/html/#reference:annotating-entities:node-entity:runtime-managed-labels

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...