Spring Data Neo4j 多态关联出现嵌入
Posted
技术标签:
【中文标题】Spring Data Neo4j 多态关联出现嵌入【英文标题】:Spring Data Neo4j polymorphic association appears embedded 【发布时间】:2015-09-16 04:25:55 【问题描述】:我在通过 rest 将关系暴露给子类型时遇到问题。 我有一个名为 Page 的抽象类:
@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 分配给歌手字段时,它抱怨它无法从 String 转换为 Musician。如果我提供 json 而不是 uri,那么它会创建一个具有相同字段值的新音乐家。 因此,当从实体引用子类型 Musician 时,它被视为不受其超类型的存储库管理。我怎样才能使歌手像链接部分下的其他相关***资源一样导出,并且可以通过接受 uri 来分配现有资源? 还是根本不可能?
【问题讨论】:
这里的继承是个坏主意吗?有人吗? 【参考方案1】:我相信您需要为 Spring Data Rest 的 Musician、Book 和 Song 单独存储库,以正确确定实体之间的关系。一旦解决了这个问题,它应该会按照您期望的方式运行 - 返回嵌入式实体的链接而不是 JSON,并在发布嵌入式实体时接受 uri。
您可能想看看这个答案,了解如何在存储库定义中处理继承:
https://***.com/a/27549198/4601679
【讨论】:
是的,但我正在寻找一种方法来管理来自一个存储库的所有子类。现在它确实支持按类型检索和在同一存储库上创建不同类型。奇怪的是,子类型之间的关系似乎是嵌入的。如果您可以从可靠来源提供参考,表明无法微调,我会接受您的回答。 我没有看到任何官方说这是不可能的,但我确实看到有人说不推荐。根据这里的 spring-data-neo4j 文档:docs.spring.io/spring-data/data-neo4j/docs/current/reference/…“提供存储库的推荐方法是为每个域类定义一个存储库接口。” 是的,但它继续:“......存储库基础设施提供的机制将自动检测它们以及其他实现类......”。 如果找不到更好的答案,我当然会接受你的答案。感谢您的关注。 建议每个类使用一个存储库也很奇怪,因为只有聚合根应该有一个专用存储库。以上是关于Spring Data Neo4j 多态关联出现嵌入的主要内容,如果未能解决你的问题,请参考以下文章
Neo4j 和 Spring-data Map 查询结果到 Jackson JsonNode
IgnoreCase Finder 不适用于 Spring Data Rest 和 Neo4J
Neo4j:不知道如何将图形映射到 Spring Data bean