Actualmente tengo una aplicación Spring Boot que utiliza Spring Data REST. Tengo una Post
entidad de dominio que tiene la relación @OneToMany
con otra entidad de dominio, Comment
. Estas clases están estructuradas de la siguiente manera:
Post.java:
@Entity public class Post { @Id @GeneratedValue private long id; private String author; private String content; private String title; @OneToMany private List 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... }
Sus repositorys JPA REST de Spring Data son implementaciones básicas de CrudRepository
:
PostRepository.java:
public interface PostRepository extends CrudRepository { }
CommentRepository.java:
public interface CommentRepository extends CrudRepository { }
El punto de entrada de la aplicación es una aplicación Spring Boot estándar y simple. Todo está configurado stock.
Application.java
@Configuration @EnableJpaRepositories @Import(RepositoryRestMvcConfiguration.class) @EnableAutoConfiguration public class Application { public static void main(final String[] args) { SpringApplication.run(Application.class, args); } }
Todo parece funcionar correctamente. Cuando ejecuto la aplicación, todo parece funcionar correctamente. Puedo PUBLICAR un nuevo objeto Post en http://localhost:8080/posts
como ese:
Cuerpo: {"author":"testAuthor", "title":"test", "content":"hello world"}
Resultado en 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" } } }
Sin embargo, cuando realizo un GET en http://localhost:8080/posts/1/comments
obtengo un objeto {}
vacío, y si bash enviar un comentario al mismo URI, obtengo un HTTP 405 Method Not Permitido.
¿Cuál es la forma correcta de crear un recurso de Comment
y asociarlo con este Post
? Me gustaría evitar la POSTING directamente a http://localhost:8080/comments
si es posible.
Primero debe publicar el comentario y, al publicar el comentario, puede crear una entidad de publicaciones de asociación.
Debería verse algo como a continuación:
http://{server:port}/comment METHOD:POST {"author":"abc","content":"PQROHSFHFSHOFSHOSF", "post":"http://{server:port}/post/1"}
y funcionará perfectamente bien.
Suponiendo que ya ha descubierto el URI de publicación y, por lo tanto, el URI del recurso de asociación (que se considera $association_uri
en lo siguiente), generalmente sigue estos pasos:
Descubra los comentarios de administración de recursos de la colección:
curl -X GET http://localhost:8080 200 OK { _links : { comments : { href : "…" }, posts : { href : "…" } } }
Siga el enlace de comments
y POST
sus datos al recurso:
curl -X POST -H "Content-Type: application/json" $url { … // your payload // … } 201 Created Location: $comment_url
Asigna el comentario a la publicación emitiendo un PUT
al URI de la asociación.
curl -X PUT -H "Content-Type: text/uri-list" $association_url $comment_url 204 No Content
Tenga en cuenta que, en el último paso, de acuerdo con la especificación de text/uri-list
, puede enviar múltiples URI que identifiquen los comentarios separados por un salto de línea para asignar múltiples comentarios a la vez.
Algunas notas más sobre las decisiones generales de diseño. Un ejemplo de publicación / comentario suele ser un gran ejemplo para un agregado, lo que significa que evitaría la referencia retrospectiva del Comment
a la Post
y también evitaría completamente el CommentRepository
. Si los comentarios no tienen un ciclo de vida propio (lo que generalmente no ocurre en una relación de estilo de composición), prefiera obtener los comentarios directamente en línea y todo el proceso de agregar y eliminar comentarios puede tratarse mejor mediante el uso de comentarios. Parche JSON . Spring Data REST ha agregado soporte para eso en la última versión candidata para la próxima versión 2.2.
Hay 2 tipos de mapeo Asociación y Composición. En caso de asociación usamos el concepto de mesa de unión como
Empleado – 1 a n-> Departamento
Por lo tanto, se crearán 3 tablas en caso de empleado de la asociación, departamento, departamento de empleado
Solo necesita crear EmployeeRepository en su código. Aparte de eso, el mapeo debería ser así:
class EmployeeEntity{ @OnetoMany(CascadeType.ALL) private List depts { } }
La entidad de tramitación no contendrá ningún mappping para la clave de forign … por lo tanto, cuando intente la solicitud POST para agregar Employee with Department en una solicitud de json única, se agregará ….
Me enfrenté al mismo escenario y tuve que eliminar la clase de repository para la entidad secundaria, ya que he usado mapeo de uno a muchos y obtengo datos a través de la entidad principal. Ahora recibo toda la respuesta con datos.