2015-06-29 68 views
1

我遇到問題,通過休息暴露與子類型的關係。 我有一個叫做頁抽象類:Spring Data Neo4j多態關聯出現嵌入式

@NodeEntity 
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "category", visible = true) 
@JsonSubTypes({ @Type(value = Musician.class), @Type(value = Book.class), 
     @Type(value = Song.class) }) 
public abstract class Page extends BaseEntity{ 

    @Fetch 
    @CreatedBy 
    private User creator; 

    @JsonSerialize(using = LocalDateTimeSerializer.class) 
    @JsonDeserialize(using = LocalDateTimeDeserializer.class) 
    @GraphProperty(propertyType = Long.class) 
    @CreatedDate private LocalDateTime timeCreated; 

    @NotEmpty 
    @Size(min = 1, max = 160) 
    @Indexed(indexType = IndexType.FULLTEXT, indexName = "search") 
    private String screenname; 

    @Fetch 
    @RelatedTo(type = "CHANNEL") 
    private Channel channel = new Channel(); 

    public Channel getChannel() { 
     return channel; 
    } 

    public void setChannel(Channel channel) { 
     this.channel = channel; 
    } 

    public String getScreenname() { 
     return screenname; 
    } 

    public void setScreenname(String screenname) { 
     this.screenname = screenname; 
    } 

    // This is to work around the bug where type name is not exported by SDR. 
    @JsonGetter(value = "category") 
    public String getType() { 
     return this.getClass().getSimpleName(); 
    } 

    public User getCreator() { 
     return creator; 
    } 

    public void setCreator(User creator) { 
     this.creator = creator; 
    } 

    public LocalDateTime getTimeCreated() { 
     return timeCreated; 
    } 

    public void setTimeCreated(LocalDateTime timeCreated) { 
     this.timeCreated = timeCreated; 
    } 

} 

兩種亞型歌曲和音樂人:

@NodeEntity 
@JsonTypeName("Song") 
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY, property="category", visible=true) 
public class Song extends Page { 

    @Fetch 
    @RelatedTo(type = "SINGER") 
    private Musician singer; 

    public Musician getSinger() { 
     return singer; 
    } 

    public void setSinger(Musician singer) { 
     this.singer = singer; 
    } 

} 

@NodeEntity 
@JsonTypeName("Musician") 
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY, property="category", visible=true) 
public final class Musician extends Page { 

} 

,這是應該管理頁面的所有子類型的存儲庫:

@RepositoryRestResource(collectionResourceRel = "pages", path = "pages") 
public interface PageRepository extends PagingAndSortingRepository<Page, Long> { 

    org.springframework.data.domain.Page<Musician> findMusicianByScreennameLike(@Param("0") String screenname, Pageable page); 

} 

當我從我的API獲得Song實例JSON的樣子:

{ 
    "uuid" : "ee9daf8b-4285-45bb-a583-e37f54284c43", 
    "timeCreated" : null, 
    "screenname" : "songtest", 
    "singer" : null, 
    "id" : 213, 
    "category" : "Song", 
    "_links" : { 
    "self" : { 
     "href" : "http://localhost:8080/api/pages/213" 
    }, 
    "channel" : { 
     "href" : "http://localhost:8080/api/pages/213/channel" 
    }, 
    "creator" : { 
     "href" : "http://localhost:8080/api/pages/213/creator" 
    } 
    } 
} 

的問題是,在歌手領域出現嵌入式。我無法將現有的音樂人與這個歌手聯繫在一起。當我嘗試將現有音樂家的URI分配給歌手字段時,它會抱怨它無法將字符串轉換爲音樂人。如果我提供json而不是uri,那麼它會創建一個具有相同字段值的新音樂人。 所以當從一個實體引用子類型的音樂家時,它被視爲不是由它的超類型的存儲庫管理。我怎樣才能讓歌手像鏈接部分下的其他關聯頂級資源一樣導出,並且可以通過接受URI來分配現有資源? 還是根本不可能?

+0

是繼承這裏是一個壞主意?任何人? – aycanadal

回答

2

我相信你會需要單獨的音樂家,書籍和歌曲的春季數據休息庫來正確確定實體之間的關係。一旦解決了問題,它應該按照您的期望行事 - 返回嵌入實體而不是JSON的鏈接,並在發佈嵌入實體時接受uri。

你可能想看看這個答案如何在你的倉庫定義處理繼承一個想法:

https://stackoverflow.com/a/27549198/4601679

+0

是的,但我正在尋找一種方法來管理一個存儲庫中的所有子類。現在它支持通過類型檢索並在同一個存儲庫上創建不同類型。亞型之間的關係似乎是嵌入式的,這很奇怪。如果您可以從可靠的來源提供參考,但這不能得到很好的調整,我會接受您的答案。 – aycanadal

+1

我沒有看到任何官方說這是不可能的,但我確實看到一些說不推薦它的東西。根據這裏的spring-data-neo4j文檔: http://docs.spring.io/spring-data/data-neo4j/docs/current/reference/html/#composing_repositories 「推薦的提供存儲庫的方式是爲每個域類定義一個存儲庫接口。「 – TLA

+0

是的,但它會繼續:「......存儲庫基礎結構提供的機制將自動檢測它們以及其他實現類......」。 – aycanadal

相關問題