2015-05-19 92 views
2

我目前正致力於一家保險公司的學士論文的企業架構管理系統。該公司希望將所有自制的應用程序(應用程序節點)顯示在Neo4J-Graphdatabase中,並將Webservice依賴關係作爲關係。除應用程序外,公司還希望持續應用程序(HAS_VERSION-Relationship)的[Maven]版本(版本 - 節點),因爲新版本可能有新的依賴關係或丟失舊版本(USES-Relationship)。這是我的觀點。我想爲每個應用程序實例提供唯一的版本子節點。如:spring-data-neo4j獨特的子節點

APPLICATION Foo 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關係。但是我希望爲每個應用程序顯式地使用唯一的版本 - 「子節點」,因爲與數據庫中的應用程序版本的USES關係應直接可見。使用唯一的版本節點,它不是。

我也實現了一個自制的方式來做到這一點。但效率不高,因爲我在數據庫上使用了許多寫和讀操作。而一些應用程序有很多版本。所以@Fetch註釋非常浪費資源。現在我很好奇,如果spring-data-neo4j已經爲我的問題提供了一個解決方案。他們是否有效地解決這個問題?

回答

1

是的,這裏是一個Spring Data Neo4j 4(當前版本爲M1)的例子。請注意,您可以如何控制持久化範圍或「深度」,以便能夠控制相關實體的獲取。

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 

       }