首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在ne4j-ogm或spring-data-new4j中动态更改实体类型?

如何在ne4j-ogm或spring-data-new4j中动态更改实体类型?
EN

Stack Overflow用户
提问于 2018-05-14 22:26:30
回答 2查看 538关注 0票数 0

有一个关于“如何在Neo4j中为节点动态添加标签”的问题。有没有一种动态改变实体类型的方法?

举个例子:

代码语言:javascript
运行
复制
    @NodeEntity
public class User {

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

}

我从https://neo4j.com/blog/spring-data-neo4j-5-0-release/中看到,我可以创建动态属性。我也可以在运行时使用动态类型吗?我希望在需要时将"User“类型动态更改为"Consumer"/"Admin"/"Producer”。实体类型不是详尽的。

提前感谢!:)

EN

回答 2

Stack Overflow用户

发布于 2018-05-17 10:30:42

除了来自类和接口的主类型之外,Set<String>上还有一个存储/管理的@Labels注释。

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

票数 1
EN

Stack Overflow用户

发布于 2018-09-10 18:23:04

@Labels机制非常棒,对于许多用例来说,我认为这是最好的解决方案。

如果你想让另一个类从你的存储库中返回,那么确实需要做更多的工作。

我是在一个与音乐相关的项目中这样做的。我有Artist (不是抽象的,对于任何我不知道它是不是乐队的地方都是完全可用的)和BandSoloArtist,它们是从Artist扩展而来的,还有其他的标签:

代码语言:javascript
运行
复制
@NodeEntity
public class Artist {}

@NodeEntity
public class Band extends Artist{}

在自定义存储库扩展中,我所知道的是:

代码语言:javascript
运行
复制
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
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50332747

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档