Actuellement, j'ai une application Spring Boot qui utilise Spring Data REST. J'ai une entité de domaine Post
qui a le @OneToMany
relation avec une autre entité de domaine, Comment
. Ces classes sont structurées comme suit:
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...
}
Commentaire.Java:
@Entity
public class Comment {
@Id
@GeneratedValue
private long id;
private String author;
private String content;
@ManyToOne
private Post post;
// Standard getters and setters...
}
Leurs référentiels Spring REST), les référentiels JPA sont des implémentations de base de CrudRepository
:
PostRepository.Java:
public interface PostRepository extends CrudRepository<Post, Long> { }
CommentRepository.Java:
public interface CommentRepository extends CrudRepository<Comment, Long> { }
Le point d’entrée de l’application est une application standard et simple de démarrage Spring Boot. Tout est configuré stock.
Application.Java
@Configuration
@EnableJpaRepositories
@Import(RepositoryRestMvcConfiguration.class)
@EnableAutoConfiguration
public class Application {
public static void main(final String[] args) {
SpringApplication.run(Application.class, args);
}
}
Tout semble fonctionner correctement. Lorsque je lance l'application, tout semble fonctionner correctement. Je peux POST un nouvel objet Post à http://localhost:8080/posts
ainsi:
Corps: {"author":"testAuthor", "title":"test", "content":"hello world"}
Résultat à 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"
}
}
}
Cependant, lorsque j'effectue une opération GET à http://localhost:8080/posts/1/comments
Je reçois un objet vide {}
est retourné et si j'essaie de POST un commentaire sur le même URI, j'obtiens une méthode HTTP 405 non autorisée.
Quelle est la bonne façon de créer une ressource Comment
et de l’associer à cette Post
? J'aimerais éviter de poster directement à http://localhost:8080/comments
si possible.
Vous devez d'abord publier le commentaire et, tout en publiant le commentaire, vous pouvez créer une entité qui publie une association.
Cela devrait ressembler à quelque chose comme ci-dessous:
http://{server:port}/comment METHOD:POST
{"author":"abc","content":"PQROHSFHFSHOFSHOSF", "post":"http://{server:port}/post/1"}
et cela fonctionnera parfaitement bien.
En supposant que vous ayez déjà découvert l’URI de publication et donc l’URI de la ressource d’association (considérée comme étant $association_uri
dans la suite), il faut généralement:
Découvrez les commentaires de gestion de la ressource de collection:
curl -X GET http://localhost:8080
200 OK
{ _links : {
comments : { href : "…" },
posts : { href : "…" }
}
}
Suivez le lien comments
et POST
vos données à la ressource:
curl -X POST -H "Content-Type: application/json" $url
{ … // your payload // … }
201 Created
Location: $comment_url
Assignez le commentaire à la publication en envoyant un PUT
à l'URI de l'association.
curl -X PUT -H "Content-Type: text/uri-list" $association_url
$comment_url
204 No Content
Notez que dans la dernière étape, selon la spécification de text/uri-list
, vous pouvez soumettre plusieurs URI identifiant des commentaires séparés par un saut de ligne pour attribuer plusieurs commentaires à la fois.
Quelques notes supplémentaires sur les décisions de conception générale. Un exemple post/comments est généralement un excellent exemple d'agrégat. Cela signifie que j'éviterais la référence arrière du Comment
au Post
et éviterais également le CommentRepository
. complètement. Si les commentaires n'ont pas eux-mêmes de cycle de vie (ce qu'ils ne font généralement pas dans une relation composition-style), vous obtenez plutôt les commentaires restitués directement dans la ligne et vous pouvez traiter l'ensemble du processus d'ajout et de suppression de commentaires en utilisant Patch JSON . Données de printemps REST a ajouté prise en charge de cela dans la dernière version candidate de la version 2.2 à venir.
Il existe 2 types de mappage Association et Composition. En cas d'association, nous avons utilisé le concept de table de jointure comme
Employé - 1 à n-> Département
Donc, 3 tables seront créées dans le cas d'un employé d'association, département, employé_département
Il vous suffit de créer EmployeeRepository dans votre code. En dehors de cette cartographie devrait être comme ça:
class EmployeeEntity{
@OnetoMany(CascadeType.ALL)
private List<Department> depts {
}
}
Depatment Entity ne contiendra pas de mappage pour la clé étrangère ... alors maintenant, lorsque vous allez essayer la demande POST) pour ajouter un employé avec département dans une demande json unique, elle sera ajoutée ....
J'ai fait face au même scénario et j'ai dû supprimer la classe de référentiel pour la sous-entité, car j'ai utilisé le mappage un à plusieurs et extraire des données via l'entité principale elle-même. Maintenant, je reçois toute la réponse avec des données.
Pour le mappage oneToMany, créez simplement un POJO pour la classe que vous souhaitez mapper, ainsi qu'une annotation @OneToMany, et en interne, il sera mappé sur cet identifiant de table.
En outre, vous devez implémenter l'interface Serializable avec la classe dans laquelle vous récupérez les données.