Atualmente tenho um aplicativo Spring Boot usando Spring Data REST. Tenho uma entidade de domínio Post
que está @OneToMany
relacionada com outra entidade de domínio Comment
,. Essas classes são estruturadas da seguinte forma:
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...
}
Seus repositórios Spring Data REST JPA são implementações básicas de CrudRepository
:
PostRepository.java:
public interface PostRepository extends CrudRepository<Post, Long> { }
CommentRepository.java:
public interface CommentRepository extends CrudRepository<Comment, Long> { }
O ponto de entrada do aplicativo é um aplicativo Spring Boot simples e padrão. Tudo está configurado em estoque.
Application.java
@Configuration
@EnableJpaRepositories
@Import(RepositoryRestMvcConfiguration.class)
@EnableAutoConfiguration
public class Application {
public static void main(final String[] args) {
SpringApplication.run(Application.class, args);
}
}
Tudo parece funcionar corretamente. Quando executo o aplicativo, tudo parece funcionar corretamente. Posso POSTAR um novo objeto Post para http://localhost:8080/posts
assim:
Corpo:
{"author":"testAuthor", "title":"test", "content":"hello world"}
Resultado em 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"
}
}
}
No entanto, quando executo um GET em http://localhost:8080/posts/1/comments
, obtenho um objeto vazio {}
retornado e, se tento fazer um POST de um comentário para o mesmo URI, obtenho um Método HTTP 405 Não Permitido.
Qual é a maneira correta de criar um Comment
recurso e associá-lo a ele Post
? Eu gostaria de evitar o POST diretamente em, http://localhost:8080/comments
se possível.
Respostas:
Você deve postar o comentário primeiro e, ao postar o comentário, pode criar uma entidade de postagem de associação.
Deve ser parecido com o que segue:
e funcionará perfeitamente bem.
fonte
author.post
é gravável (por exemplo, tendo um setter ou@JsonValue
anotação)Supondo que você já tenha descoberto o URI da postagem e, portanto, o URI do recurso de associação (considerado como
$association_uri
o seguinte), geralmente ocorre estas etapas:Descubra o recurso de coleta de comentários de gerenciamento:
Siga o
comments
link ePOST
seus dados para o recurso:Atribua o comentário à postagem emitindo um
PUT
para o URI da associação.Observe que na última etapa, de acordo com a especificação de
text/uri-list
, você pode enviar vários URIs identificando comentários separados por uma quebra de linha para atribuir vários comentários de uma vez.Mais algumas notas sobre as decisões gerais de design. Um exemplo de postagem / comentários geralmente é um ótimo exemplo para um agregado, o que significa que eu evitaria a referência inversa de
Comment
aPost
e também evitariaCommentRepository
completamente. Se os comentários não têm um ciclo de vida por conta própria (o que geralmente não acontece em um relacionamento de estilo de composição), você prefere obter os comentários renderizados in-line diretamente e todo o processo de adição e remoção de comentários pode ser tratado usando Patch JSON . Spring Data REST adicionou suporte para isso no candidato a lançamento mais recente para a próxima versão 2.2.fonte
@JoinColumn(nullable=false)
)? Não seria possível primeiro POSTAR o filho e, em seguida, PUT / PATCH na associação pai.Existem 2 tipos de associação e composição de mapeamento. Em caso de associação, usamos o conceito de tabela de junção como
Funcionário - 1 para n-> Departamento
Portanto, 3 tabelas serão criadas no caso de Association Employee, Department, Employee_Department
Você só precisa criar o EmployeeRepository em seu código. Além desse mapeamento, deve ser assim:
A Entidade de Depósito não conterá nenhum mapeamento para chave estrangeira ... então agora, quando você tentar a solicitação POST para adicionar Funcionário com Departamento em uma única solicitação json, ela será adicionada ....
fonte
Eu enfrentei o mesmo cenário e tive que remover a classe de repositório para a subentidade, pois usei um para muitos mapeando e extraí dados através da própria entidade principal. Agora estou recebendo a resposta completa com dados.
fonte
Para o mapeamento oneToMany, basta fazer um POJO para a classe que você deseja mapear e a anotação @OneToMany para ela e, internamente, ele o mapeará para esse id de tabela.
Além disso, você precisa implementar a interface serializável para a classe que está recuperando os dados.
fonte