Spring Data Rest:检测到具有相同关系类型的多个关联链接

时间:2014-09-14 10:30:00

标签: java spring spring-mvc spring-data spring-data-rest

关于这个问题,我检查了Spring Data Rest Ambiguous Association Exception,但无法让它为我工作。

正如您在下面的代码中所看到的,我添加了@RestResource注释rel等于其他值。

与上述问题类似,POST请求有效,但GET请求会抛出关于具有相同关系类型的多个关联链接的异常:

  

"无法编写JSON:检测到多个关联链接   关系类型!消除关联歧义   @ org.springframework.data.rest.core.annotation.RestResource(相对= createdBy,   exported = true,path =,   description=@org.springframework.data.rest.core.annotation.Description(值=))   @javax.persistence.ManyToOne(optional = true,targetEntity = void,   cascade = [],fetch = EAGER)   @ javax.persistence.JoinColumn(referencedColumnName = ASSIGNABLE_ID,   nullable = false,unique = false,name = CREATED_BY,updatable = true,   columnDefinition =,foreignKey = @ javax.persistence.ForeignKey(name =,   value = CONSTRAINT,foreignKeyDefinition =),table =,insertable = true)   私人com.ag.persistence.domain.PersonEntity   com.ag.persistence.domain.TeamEntity.createdBy使用@RestResource!   (通过参考链:   org.springframework.hateoas.PagedResources [\" _embedded \"] - > java.util.UnmodifiableMap [\"人\"] - > java.util.ArrayList中[ 0]);   嵌套异常是   com.fasterxml.jackson.databind.JsonMappingException:检测到多个   关联链接具有相同的关系类型!消除关联歧义   @ org.springframework.data.rest.core.annotation.RestResource(相对= createdBy,   exported = true,path =,   description=@org.springframework.data.rest.core.annotation.Description(值=))   @javax.persistence.ManyToOne(optional = true,targetEntity = void,   cascade = [],fetch = EAGER)   @ javax.persistence.JoinColumn(referencedColumnName = ASSIGNABLE_ID,   nullable = false,unique = false,name = CREATED_BY,updatable = true,   columnDefinition =,foreignKey = @ javax.persistence.ForeignKey(name =,   value = CONSTRAINT,foreignKeyDefinition =),table =,insertable = true)   私人com.ag.persistence.domain.PersonEntity   com.ag.persistence.domain.TeamEntity.createdBy使用@RestResource!   (通过参考链:   org.springframework.hateoas.PagedResources [\" _embedded \"] - > java.util.UnmodifiableMap [\"人\"] - > java.util.ArrayList中[ 0])"

这个错误似乎发生在这个课程中:

@Entity
@Table(name = "team")
public class TeamEntity extends AssignableEntity {
    private String name;
    private LocalDateTime createdDate;
    private LocalDateTime modifiedDate;
    private Collection<MembershipEntity> memberships;
    private PersonEntity createdBy;
    private PersonEntity modifiedBy;

    @Basic
    @Column(name = "NAME")
    public String getName() {
        return name;
    }

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

    @Basic
    @Column(name = "CREATED_DATE")
    public LocalDateTime getCreatedDate() {
        return createdDate;
    }

    public void setCreatedDate(LocalDateTime createdDate) {
        this.createdDate = createdDate;
    }

    @Basic
    @Column(name = "MODIFIED_DATE")
    public LocalDateTime getModifiedDate() {
        return modifiedDate;
    }

    public void setModifiedDate(LocalDateTime modifiedDate) {
        this.modifiedDate = modifiedDate;
    }

    @OneToMany(mappedBy = "team")
    public Collection<MembershipEntity> getMemberships() {
        return memberships;
    }

    public void setMemberships(Collection<MembershipEntity> memberships) {
        this.memberships = memberships;
    }

    @RestResource(rel = "team_createdBy")
    @ManyToOne
    @JoinColumn(name = "CREATED_BY", referencedColumnName = "ASSIGNABLE_ID", nullable = false)
    public PersonEntity getCreatedBy() {
        return createdBy;
    }

    public void setCreatedBy(PersonEntity createdBy) {
        this.createdBy = createdBy;
    }

    @RestResource(rel = "team_modifiedBy")
    @ManyToOne
    @JoinColumn(name = "MODIFIED_BY", referencedColumnName = "ASSIGNABLE_ID", nullable = false)
    public PersonEntity getModifiedBy() {
        return modifiedBy;
    }

    public void setModifiedBy(PersonEntity modifiedBy) {
        this.modifiedBy = modifiedBy;
    }
}

具有讽刺意味的是,我没有访问此特定资源。我还有createdBymodifiedBy的其他资源 - 这是导致此问题的资源吗?

2 个答案:

答案 0 :(得分:2)

我怀疑您的exported = false对象上可能有PersonEntity。因此,PersonEntity中的所有引用都会添加到_links的{​​{1}}部分。由于两个TeamEntity对象都有PersonEntity引用,因此它们与createdBy引用冲突。

要了解正在发生的事情,此示例可能有所帮助:

TeamEntity.createdBy

就我而言,因为class Answer { Question q; //JPA ManyToOne back-reference } class Question { List<Answer> as; // JPA OneToMany reference } class UserAnswer { Answer a; Question q; } 只能存在于Answer中,我们Question上会有以下内容,以防止导出答案:

AnswerResource

这导致@RestResource(exported = false) 个对象在父对象中被序列化,而不是Answer部分中的引用,这最终导致了问题......

序列化_links时,它会呈现如下内容:

UserAnswer

请注意&#34; _links.question&#34;上面来自{ "answer" : { "creationDate" : "2014-09-18T17:28:31.000+0000", "modificationDate" : "2014-09-18T17:28:31.000+0000", "answerText" : "Vendas", }, "_links" : { "self" : { "href" : "http://localhost:9090/data/userAnswers/15" }, "question" : { "href" : "http://localhost:9090/data/userAnswers/15/question" } } }

因此,如果您向Answer添加Question,则会看到您询问的错误,因为UserAnswer本身想要包含_link引用UserAnswer

在您的情况下,我认为您的QuestionPersonEntity都有TeamEntity个引用。

我不能100%确定解决方案是什么,我不知道您是否可以指定分层createdBy名称。

答案 1 :(得分:1)

简短回答:为所有(或至少更多)实体添加Spring Data存储库。 (在这种情况下,听起来你需要创建一个PersonRepository)。

答案很长:

Spring Data Rest使用_links来避免发送回整个JSON树,但它只能将_links链接到具有存储库的映射实体。

如果没有实体的存储库,Spring不能使用链接,而只是将整个JSON对象放在响应中。

我认为这个例外发生的事情是,一个较低的二级关系被放入_link,并且其中不止一个具有相同的名称。

我并非100%确定我理解这一切,但是当我只为几个实体拥有存储库时,我有同样的例外,当我为每个实体创建一个存储库时,问题就消失了。