2016-04-26 3 views
4

У меня есть простой проект, выполняемый Spring-Data-Rest раскрыть некоторые объекты с помощью API Rest, как этот (упрощенный, минус сеттеры/Getters):Настройка Spring Data Rest @ManyToMany отношения обработки

@Entity 
public class Group { 

    @Id 
    @GeneratedValue 
    private int id; 

    ... 

} 

@Entity 
public class Person{ 

    @Id 
    @GeneratedValue 
    private int id; 

    ... 

} 

Теперь, очевидно, каждая группа может иметь людей в качестве членов, которые можно легко решить с помощью @ManyToMany. К сожалению (или обычно?) Членство в группе содержит больше информации, чем просто «является членом». Например, он должен также включать в себя информацию «admin of» или «скрытый член».

Это, естественно, приводит к дополнительному лицу ...

@Entity 
public class GroupMember { 

    @OneToOne(optional = false) 
    @JoinColumn(updatable = false) 
    private Person member; 

    @OneToOne(optional = false) 
    @JoinColumn(updatable = false) 
    private Group group; 

    private boolean admin; 

    private boolean hidden; 

     ... 

} 

Что бы не так уж плохо, но, к сожалению, приводит к проблеме ... Я уже не могу просто добавить пользователей в группу по POST Ингам a text/uri-list (например) /groups/1/members, но вместо этого я должен создать новый объект GroupMember, разместив его до /groupMembers/, который, imho, не так удобен и разрывает сплоченность группы REST 'tree'.

Как я могу решить эту проблему и разрешить простой POST создавать (основной) GroupMember со значениями по умолчанию? Конечно, я мог бы разместить новый @RepositoryRestController там, который улавливает любой запрос POST до /groups/1/members, но это предотвращает список text/uri-list (поскольку он, похоже, не поддерживает это). Я мог бы определить новый объект, например, с идентификатором человека, но это сломало бы поток, простое размещение списка ссылок было бы лучше.

Другим способом было бы найти способ отображения самого Hibernate @ManyToMany без дополнительной сущности ... Но я не знаю, такой способ ...

+0

весна-данные-покоя должен иметь возможность, чтобы позволить вам указать присоединиться объект таблицы, а затем ль t структура uri уменьшается до тех пор, пока вы укажете, как уменьшается столбец каждой таблицы соединений. – kenny

ответ

1

Если вы работаете с остальной весной данных и хотите обрабатывать text/uri-list в пользовательском контроллере можно передать значение с помощью параметра типа Resources так:

@RequestBody Resources<Object> incoming 

Вы получаете URIs по телефону incoming.getLinks()

вы можете посмотреть на контроллере пружинных данных покоя в качестве эталона - org.springframework.data.rest.webmvc.RepositoryPropertyReferenceController#createPropertyReference

+1

Спасибо, это было очень полезно. Я также нашел способ использовать UriToEntityConverter, поэтому теперь я могу переопределить поведение POST/PUT, чтобы принимать ссылки на человека и автоматически создавать для них объекты GroupMember. –

0

Я думаю, что вы правы, что это лучше всего иметь третью организацию, GroupMember, как вы предложили. Разве вы не можете показать конечную точку API, которая позволяет отправлять сообщения в /groups/1/members? Для вас, похоже, вам понадобится иметь бизнес-логику в вашем контроллере, которая разрешает соответствующие Person (ы) и создает экземпляры GroupMember. Мне кажется, что это подходящее место для этой бизнес-логики.

+0

Как я уже сказал, я бы предпочел просто отправить пост в список членов и автоматически создать группы. К сожалению, мой собственный BasePathAwareController даже не способен обрабатывать текстовые/uri-list Content-Types (результаты в 415), поэтому я даже не могу имитировать это, но мне нужно было бы создать json-представление этого, и это сломало бы поток (потому что это будет отличаться от обработки других коллекций). –