Spring Data Rest: обнаружено несколько ассоциативных ссылок с одинаковым типом отношения

Что касается этого вопроса, я проверил Spring Data Rest Ambiguous Association Exception, но не смог ' чтобы заставить его работать для меня.

Как вы можете видеть в моем коде ниже, я добавил аннотацию @RestResource с rel, равным некоторому другому значению.

Подобно указанному выше вопросу, запросы POST работают, но запросы GET вызывают исключение о нескольких ссылках связи с одним и тем же типом отношения:

«Не удалось записать JSON: обнаружено несколько ассоциативных ссылок с одинаковым типом отношения! Устранение неоднозначности ассоциации @ org.springframework.data.rest.core.annotation.RestResource (rel = createdBy, exported = true, path =, [email protected]. data.rest.core.annotation.Description (value =)) @ javax.persistence.ManyToOne (необязательно = true, targetEntity = void, cascade = [], fetch = EAGER) @ javax.persistence.JoinColumn (referencedColumnName = ASSIGNABLE_ID, допускает значение NULL = false, unique = false, name = CREATED_BY, updatable = true, columnDefinition =, [email protected] (name =, value = CONSTRAINT, foreignKeyDefinition =), table =, insertable = true) private com.ag. persistence.domain.PersonEntity com.ag.persistence.domain.TeamEntity.createdBy using @RestResource! (через цепочку ссылок: org.springframework.hateoas.PagedResources [\ "_ embedded \"] -> java.util.UnmodifiableMap [\ "люди \ "] -> java.util.ArrayList [0]); вложенное исключение - com.fasterxml.jackson.databind.JsonMappingExce ption: Обнаружено несколько ассоциативных ссылок с одинаковым типом отношения! Устранение неоднозначности ассоциации @ org.springframework.data.rest.core.annotation.RestResource (rel = createdBy, exported = true, path =, description=@org.springframework.data.rest.core.annotation.Description (value =)) @ 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 =, [email protected] (name =, value = CONSTRAINT, foreignKeyDefinition =), table =, insertable = true) private com.ag.persistence.domain.PersonEntity com.ag.persistence.domain.TeamEntity. createdBy с помощью @RestResource! (через цепочку ссылок: org.springframework.hateoas.PagedResources [\ "_ embedded \"] -> java.util.UnmodifiableMap [\ "people \"] -> 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;
    }
}

По иронии судьбы, я не получаю доступ к этому конкретному ресурсу. У меня также есть другие ресурсы с createdBy и _5 _ - это причина этой проблемы?


person Chad    schedule 14.09.2014    source источник
comment
Есть ли у какой-либо другой сущности свойство createdBy? Например, PersonEntity?   -  person a better oliver    schedule 15.09.2014
comment
Все мои объекты имеют четыре поля: createdBy, modifiedBy, createdDate и modifiedDate   -  person Chad    schedule 15.09.2014
comment
Это могло быть проблемой. Взгляните на этот вопрос . Оба PersonEntity в вашем TeamEntity вероятно содержат ссылку createdBy.   -  person a better oliver    schedule 15.09.2014
comment
Эти поля нужны мне для редактирования. Есть ли способ решения этой проблемы?   -  person Chad    schedule 15.09.2014
comment
Есть ли у PersonEntity и TeamEntity свои репозитории? Пожалуйста, также вставьте эти классы.   -  person freakman    schedule 17.09.2014
comment
В этом конкретном сценарии нет, у меня нет репозиториев для этого. Но я попытался создать аннотированный репозиторий, чтобы предоставить конечную точку для тех ресурсов, которые решили эту проблему, однако я хотел бы знать, есть ли способ, не раскрывая конечную точку, для этого.   -  person Chad    schedule 17.09.2014
comment
извините, не знаю ... на самом деле я сталкиваюсь с аналогичными проблемами в данный момент ... добавление репозиториев помогло, но теперь созданные _links не имеют смысла   -  person freakman    schedule 17.09.2014


Ответы (2)


Я подозреваю, что на вашем PersonEntity объекте может быть exported = false. По этой причине все ссылки в PersonEntity будут добавлены в раздел _links вашего 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 сериализуется, он отображает что-то вроде этого:

{
  "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"
    }
  }
}

Обратите внимание, что "_links.question" выше взят из Answer!

Поэтому, если вы добавите Question к UserAnswer, вы увидите ошибку, о которой спрашиваете, потому что сам UserAnswer также хочет включить ссылку _link на Question.

В вашем случае я думаю, что у вас PersonEntity и вашего TeamEntity есть createdBy ссылок.

Я еще не на 100% уверен, что это за решение, я не знаю, можно ли указать иерархические rel имена.

person JBCP    schedule 15.10.2014
comment
Я создал для этого проблему JIRA, поскольку подозреваю, что это ошибка: jira.spring.io/browse/ ДАТАРЕСТ-520 - person ; 15.04.2015

Краткий ответ: добавьте репозитории Spring Data для ВСЕХ (или хотя бы большего количества) ваших сущностей. (В этом случае похоже, что вам нужно создать PersonRepository).

Длинный ответ:

Spring Data Rest использует _links, чтобы не отправлять обратно все дерево JSON, но он может создавать _links только для сопоставленных сущностей, у которых есть репозитории.

Если для объекта нет репозитория, Spring не может использовать ссылку и вместо этого просто поместит весь объект JSON в ответ.

Я ДУМАЮ, что происходит с этим исключением, так это то, что отношение более низкого, второго уровня помещается в _link, и несколько из них имеют одно и то же имя.

Я не уверен на 100%, что понимаю все это, но у меня было такое же исключение, когда были репозитории только для нескольких сущностей, и когда я сделал репозиторий для каждой отдельной сущности, проблема исчезла.

person LordBlackhole    schedule 20.05.2016