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, тогда он будет добавлен....