РАЗМЕЩЕНИЕ ассоциации подресурсов @OneToMany в Spring Data REST
В настоящее время у меня есть приложение Spring Boot, использующее Spring Data REST. У меня есть субъект домена Post
который имеет @OneToMany
отношение к другому объекту домена, Comment
, Эти классы структурированы следующим образом:
Post.java:
@Entity
public class Post {
@Id
@GeneratedValue
private long id;
private String author;
private String content;
private String title;
@OneToMany
private List<Comment> comments;
// Standard getters and setters...
}
Comment.java:
@Entity
public class Comment {
@Id
@GeneratedValue
private long id;
private String author;
private String content;
@ManyToOne
private Post post;
// Standard getters and setters...
}
Их репозитории Spring Data REST JPA являются основными реализациями CrudRepository
:
PostRepository.java:
public interface PostRepository extends CrudRepository<Post, Long> { }
CommentRepository.java:
public interface CommentRepository extends CrudRepository<Comment, Long> { }
Точка входа в приложение - это стандартное простое приложение Spring Boot. Все настроено на складе.
Application.java
@Configuration
@EnableJpaRepositories
@Import(RepositoryRestMvcConfiguration.class)
@EnableAutoConfiguration
public class Application {
public static void main(final String[] args) {
SpringApplication.run(Application.class, args);
}
}
Кажется, все работает правильно. Когда я запускаю приложение, кажется, все работает правильно. Я могу ЗАПИСАТЬ новый объект Post в http://localhost:8080/posts
вот так:
Тело: {"author":"testAuthor", "title":"test", "content":"hello world"}
Результат на http://localhost:8080/posts/1
:
{
"author": "testAuthor",
"content": "hello world",
"title": "test",
"_links": {
"self": {
"href": "http://localhost:8080/posts/1"
},
"comments": {
"href": "http://localhost:8080/posts/1/comments"
}
}
}
Тем не менее, когда я выполняю GET в http://localhost:8080/posts/1/comments
Я получаю пустой объект {}
возвращается, и если я пытаюсь отправить комментарий к тому же URI, я получаю HTTP 405 Метод не разрешен.
Как правильно создать Comment
ресурс и связать его с этим Post
? Я хотел бы избежать POSTing непосредственно к http://localhost:8080/comments
если возможно.
5 ответов
Сначала вы должны опубликовать комментарий, и во время публикации комментария вы можете создать объект публикации сообщений.
Это должно выглядеть примерно так:
http://{server:port}/comment METHOD:POST
{"author":"abc","content":"PQROHSFHFSHOFSHOSF", "post":"http://{server:port}/post/1"}
и это будет прекрасно работать.
Предполагая, что вы уже обнаружили почтовый URI и, следовательно, URI ресурса ассоциации (считается $association_uri
в следующем), как правило, предпринимаются следующие шаги:
Откройте для себя ресурс коллекции, управляющий комментариями:
curl -X GET http://localhost:8080 200 OK { _links : { comments : { href : "…" }, posts : { href : "…" } } }
Следовать
comments
ссылка иPOST
Ваши данные на ресурс:curl -X POST -H "Content-Type: application/json" $url { … // your payload // … } 201 Created Location: $comment_url
Назначьте комментарий к сообщению, выполнив
PUT
в URI ассоциации.curl -X PUT -H "Content-Type: text/uri-list" $association_url $comment_url 204 No Content
Обратите внимание, что на последнем шаге, согласно спецификации text/uri-list
Вы можете отправить несколько URI, идентифицирующих комментарии, разделенные разрывом строки, чтобы назначить несколько комментариев одновременно.
Еще несколько заметок об общих дизайнерских решениях. Пример публикации / комментария, как правило, является отличным примером для совокупности, что означает, что я бы избегал обратной ссылки из Comment
к Post
а также избегать CommentRepository
полностью. Если комментарии сами по себе не имеют жизненного цикла (чего обычно не бывает в отношениях стиля композиции), вы, скорее, получите комментарии, встроенные напрямую, и весь процесс добавления и удаления комментариев можно скорее решить с помощью JSON Patch. Spring Data REST добавил поддержку для этого в последнем выпуске кандидата для следующей версии 2.2.
Существует 2 типа картографических ассоциаций и композиций. В случае ассоциации мы использовали концепцию таблицы соединений
Сотрудник - от 1 до н-> отдел
Таким образом, 3 таблицы будут созданы в случае сотрудника ассоциации, отдела, Employee_Department
Вам нужно только создать EmployeeRepository в своем коде. Помимо этого отображения должно быть так:
class EmployeeEntity{
@OnetoMany(CascadeType.ALL)
private List<Department> depts {
}
}
Entatment Entity не будет содержать сопоставления для forign-ключа... так что теперь, когда вы попробуете POST-запрос на добавление Employee with Department в одном json-запросе, он будет добавлен....
Я столкнулся с тем же сценарием, и мне пришлось удалить класс репозитория для подобъекта, поскольку я использовал сопоставление один ко многим и извлекал данные через сам основной объект. Теперь я получаю полный ответ с данными.
Для отображения oneToMany просто создайте POJO для того класса, который вы хотите отобразить, и аннотации @OneToMany к нему, и он будет внутренне сопоставлен с этим идентификатором таблицы.
Кроме того, вам необходимо реализовать интерфейс Serializable для класса, который вы извлекаете Данные.