wake-up-neo.com

POSTEN einer @ OneToMany-Subressourcenzuordnung in Spring Data REST

Derzeit habe ich eine Spring Boot-Anwendung, die Spring Data REST verwendet. Ich habe eine Domain-Entität Post, die die Beziehung @OneToMany Zu einer anderen Domain-Entität, Comment, hat. Diese Klassen sind wie folgt aufgebaut:

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...
}

Ihre Spring Data REST JPA-Repositorys sind grundlegende Implementierungen von CrudRepository:

PostRepository.Java:

public interface PostRepository extends CrudRepository<Post, Long> { }

CommentRepository.Java:

public interface CommentRepository extends CrudRepository<Comment, Long> { }

Der Anwendungseinstiegspunkt ist eine standardmäßige, einfache Spring Boot-Anwendung. Alles ist serienmäßig konfiguriert.

Anwendung.Java

@Configuration
@EnableJpaRepositories
@Import(RepositoryRestMvcConfiguration.class)
@EnableAutoConfiguration
public class Application {

    public static void main(final String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Alles scheint richtig zu funktionieren. Wenn ich die Anwendung ausführe, scheint alles korrekt zu funktionieren. Ich kann POST ein neues Post-Objekt an http://localhost:8080/posts Wie folgt senden:

Body: {"author":"testAuthor", "title":"test", "content":"hello world"}

Ergebnis bei 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"
        }
    }
}

Wenn ich jedoch ein GET bei http://localhost:8080/posts/1/comments Durchführe, wird ein leeres Objekt {} Zurückgegeben, und wenn ich versuche, POST einen Kommentar zu derselben URI zu verfassen, wird I Rufen Sie eine HTTP 405-Methode ab. Nicht zulässig.

Wie kann eine Comment Ressource korrekt erstellt und mit dieser Post verknüpft werden? Ich möchte es nach Möglichkeit vermeiden, direkt an http://localhost:8080/comments Zu senden.

100
ccampo

Sie müssen zuerst den Kommentar posten und während Sie den Kommentar posten, können Sie eine Entität für Assoziationsbeiträge erstellen.

Es sollte ungefähr so ​​aussehen:

http://{server:port}/comment METHOD:POST

{"author":"abc","content":"PQROHSFHFSHOFSHOSF", "post":"http://{server:port}/post/1"}

und es wird einwandfrei funktionieren.

48
Chetan Kokil

Angenommen, Sie haben bereits den Post-URI und damit den URI der Assoziationsressource (gilt als $association_uri im Folgenden) werden im Allgemeinen die folgenden Schritte ausgeführt:

  1. Entdecken Sie die Kommentare zum Verwalten von Sammlungsressourcen:

    curl -X GET http://localhost:8080
    
    200 OK
    { _links : {
        comments : { href : "…" },
        posts :  { href : "…" }
      }
    }
    
  2. Folgen Sie dem Link comments und POST Ihrer Daten zur Ressource:

    curl -X POST -H "Content-Type: application/json" $url 
    { … // your payload // … }
    
    201 Created
    Location: $comment_url
    
  3. Ordnen Sie den Kommentar dem Beitrag zu, indem Sie der Zuordnungs-URI ein PUT zuweisen.

    curl -X PUT -H "Content-Type: text/uri-list" $association_url
    $comment_url
    
    204 No Content
    

Beachten Sie, dass im letzten Schritt gemäß der Spezifikation von text/uri-list , Sie können mehrere URIs mit durch einen Zeilenumbruch getrennten Kommentaren senden, um mehrere Kommentare gleichzeitig zuzuweisen.

Noch ein paar Anmerkungen zu den allgemeinen Entwurfsentscheidungen. Ein Post/Comments-Beispiel ist normalerweise ein großartiges Beispiel für ein Aggregat. Das bedeutet, dass ich den Rückverweis vom Comment zum Post und auch den CommentRepository vermeiden würde. vollständig. Wenn die Kommentare keinen eigenen Lebenszyklus haben (was normalerweise in einer kompositorischen Beziehung nicht der Fall ist), werden die Kommentare eher direkt inline gerendert, und der gesamte Prozess des Hinzufügens und Entfernens von Kommentaren kann eher mithilfe von behandelt werden JSON-Patch . Spring Data REST hat dies wird unterstützt im neuesten Release Candidate für die kommende Version 2.2 hinzugefügt.

53
Oliver Drotbohm

Es gibt zwei Arten der Zuordnung von Zuordnung und Zusammensetzung. Im Falle einer Assoziation verwendeten wir das Join Table Konzept wie

Mitarbeiter - 1 bis n-> Abteilung

Im Fall von Association Employee, Department, Employee_Department werden also 3 Tabellen erstellt

Sie müssen nur das EmployeeRepository in Ihrem Code erstellen. Ansonsten sollte das Mapping so aussehen:

class EmployeeEntity{

@OnetoMany(CascadeType.ALL)
   private List<Department> depts {

   }

}

Die Abteilungseinheit enthält kein Mappping für den Fremdschlüssel. Wenn Sie also die POST) -Anforderung zum Hinzufügen eines Mitarbeiters mit Abteilung in einer einzelnen JSON-Anforderung ausführen, wird sie hinzugefügt.

2
Naveen Goyal

Ich sah mich mit demselben Szenario konfrontiert und musste die Repository-Klasse für die Unterentität entfernen, da ich eine oder mehrere Zuordnungen verwendet und Daten durch die Hauptentität selbst gezogen habe. Jetzt erhalte ich die gesamte Antwort mit Daten.

1
Selva

Für ein OneToMany-Mapping erstellen Sie einfach ein POJO für die Klasse, die Sie mappen möchten, und eine @OneToMany-Annotation, die intern dieser Tabellen-ID zugeordnet wird.

Außerdem müssen Sie die Serializable-Schnittstelle für die Klasse implementieren, für die Sie die Daten abrufen.

0
Sunny Chaurasia