spring-data-neo4j 的唯一子节点

Unique subnodes with spring-data-neo4j

我目前正在为我在一家保险公司的学士论文研究企业架构管理系统。公司希望在 Neo4J-Graph 数据库中显示所有自制应用程序(应用程序节点),并将 Web 服务依赖关系作为关系。除了应用程序,公司还希望保留应用程序 (HAS_VERSION-Relationship) 的 [Maven] 版本 (Version-Node),因为新版本可能有新的依赖项或丢失旧的依赖项 (USES-Relationship)。这是我的观点。我想为每个应用程序实例提供唯一的版本子节点。如:

应用程序 HAS_VERSION 1.0; 1.1; 2.0 和应用栏 HAS_VERSION 1.0; 2.0; 3.0;但是两个应用程序的版本节点 1.0 和 2.0 应该是单独的节点。所以这个例子应该在图形数据库中显示总共 8 个节点(2 个应用程序和 6 个版本)。他们是使用 spring-data-neo4j 实现这一点的直接方法吗?我已经尝试在我的应用程序 POJO-Class 中的版本集上使用 @Unique 注释。但这会导致每个版本都有唯一的节点。所以上面的例子在数据库中显示了 6 个节点(2 个应用程序和 4 个版本)。并且这两个应用程序都与版本节点 1.0、2.0 具有 HAS_VERSION 关系。但我希望每个应用程序都具有明确唯一的 Version-"subnodes",因为与依赖应用程序版本的 USES 关系应该在数据库中直接可见。对于唯一的版本节点,它不是。

我还实现了一种自制的方法来做到这一点。但它不是很有效,因为我确实在数据库上使用了很多写入和读取操作。并且一些应用程序有很多版本。所以@Fetch 注解是非常浪费资源的。现在我很好奇 spring-data-neo4j 是否已经为我的问题提供了解决方案。他们能有效地解决这个问题吗?

是的,这里有一个 Spring Data Neo4j 4 的例子(目前是 M1 版本)。请注意如何控制持久性范围或 "depth" 以便能够控制相关实体的获取。

Application.java

@NodeEntity
public class Application {

    Long id;
    String name;
    @Relationship(type="HAS_VERSION", direction = "OUTGOING")
    Set<Version> versions = new HashSet<>();

    public Application() {
    }

    public Application(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void addVersion(Version version) {
        versions.add(version);
    }

    public Set<Version> getVersions() {
        return versions;
    }

    public Long getId() {
        return id;
    }
}

Version.java

@NodeEntity
public class Version {

    Long id;

    String versionNumber;

    @Relationship(type = "HAS_VERSION", direction = "INCOMING")
    Application application;


    public Version() {
    }

    public Version(String versionNumber) {
        this.versionNumber = versionNumber;
    }

    public String getVersionNumber() {
        return versionNumber;
    }

    public void setVersionNumber(String versionNumber) {
        this.versionNumber = versionNumber;
    }

    public Application getApplication() {
        return application;
    }

    public void setApplication(Application application) {
        this.application = application;
    }

    public Long getId() {
        return id;
    }
}

存储库

public interface VersionRepository extends GraphRepository<Version> {

}

public interface ApplicationRepository extends GraphRepository<Application>{

}

还有一个测试:

     @Test
                public void testDomain() {
                    Application foo = new Application("Foo");
                    Version foo10 = new Version("1.0"); //create a NEW version
                    Version foo11 = new Version("1.1"); //create a NEW version
                    Version foo20 = new Version("2.0"); //create a NEW version
                    foo.addVersion(foo10);
                    foo.addVersion(foo11);
                    foo.addVersion(foo20);
                    applicationRepository.save(foo);

                    Application bar = new Application("Bar");
                    Version bar10 = new Version("1.0"); //create a NEW version
                    Version bar20 = new Version("2.0"); //create a NEW version
                    Version bar30 = new Version("3.0"); //create a NEW version
                    bar.addVersion(bar10);
                    bar.addVersion(bar20);
                    bar.addVersion(bar30);
                    applicationRepository.save(bar);

                    session.clear();

                    assertEquals(2, applicationRepository.count()); //2 apps
                    assertEquals(6, versionRepository.count()); //6 versions

                    session.clear();

                    Application barWithoutVersionsLoaded = 
applicationRepository.findOne(bar.getId(),0); 

       //Depth=0 will only load the application and properties on the application node 
       //but not its related objects. 
       //If you don't specify depth, it defaults to 1
                    assertEquals("Bar", barWithoutVersionsLoaded.getName());
                    assertEquals(0, barWithoutVersionsLoaded.getVersions().size()); //No versions loaded

                }