POSTing объединение @OneToMany-под-ресурсов в Spring Data REST
В настоящее время у меня есть приложение загрузки Spring с использованием 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. Все настроено на запас.
Application.java
@Configuration
@EnableJpaRepositories
@Import(RepositoryRestMvcConfiguration.class)
@EnableAutoConfiguration
public class Application {
public static void main(final String[] args) {
SpringApplication.run(Application.class, args);
}
}
Все работает правильно. Когда я запускаю приложение, все работает правильно. Я могу отправить POST новый объект 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
, я возвращаю пустой объект {}
, и если я пытаюсь отправить сообщение POST на тот же URI, я получаю метод HTTP 405, который не разрешен.
Каков правильный способ создания ресурса Comment
и связать его с этим Post
? Я бы хотел, чтобы избежать POSTing непосредственно http://localhost:8080/comments
, если это возможно.
Ответы
Ответ 1
Сначала вы должны опубликовать комментарий, а во время публикации комментария вы можете создать объект сообщений ассоциации.
Он должен выглядеть примерно так:
http://{server:port}/comment METHOD:POST
{"author":"abc","content":"PQROHSFHFSHOFSHOSF", "post":"http://{server:port}/post/1"}
и он будет работать отлично.
Ответ 2
Предполагая, что вы уже обнаружили 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, идентифицирующих комментарии, разделенные линией break для одновременного назначения нескольких комментариев.
Несколько примечаний к общим проектным решениям. Пример post/comments обычно является отличным примером для совокупности, что означает, что я бы избегал обратной ссылки из Comment
в POST
, а также полностью избегал CommentRepository
. Если комментарии не имеют жизненного цикла сами по себе (которые обычно не имеют отношения к композиционному стилю), вы скорее получаете комментарии, отображаемые в строке напрямую, и весь процесс добавления и удаления комментариев может быть рассмотрен с помощью Патч JSON. Spring Data REST добавила поддержку для этого в последнем выпуске для предстоящей версии 2.2.
Ответ 3
Я столкнулся с одним и тем же сценарием, и мне пришлось удалить класс репозитория для субобъекта, поскольку я использовал одно-много сопоставление и вытаскивание данных через основную сущность. Теперь я получаю весь ответ с данными.
Ответ 4
Существует 2 типа картографирования Association and Composition. В случае ассоциации мы использовали концепцию соединения таблицы, например
Сотрудник - от 1 до n- > Отдел
Таким образом, 3 таблицы будут созданы в случае Ассоциации
Сотрудник, отдел, Employee_Department
Вам нужно только создать EmployeeRepository в вашем коде. Помимо этого отображения должно быть так:
class EmployeeEntity{
@OnetoMany(CascadeType.ALL)
private List<Department> depts {
}
}
Depatment Entity не будет содержать mappping для forign key... поэтому теперь, когда вы попробуете запрос POST для добавления Employee with Department в один запрос json, тогда он будет добавлен....