Использование Spring Data REST и Spring Data JPA, я хочу обновить коллекцию дочерних сущностей по корню агрегата. В качестве примера для демонстрации предположим, что у меня есть объект Post
, который имеет отношение «один ко многим» с объектом Comment
. Post
имеет собственный репозиторий данных Spring; Comment
не потому, что он доступен только через Post
.Spring Data REST/JPA - обновленная коллекция OneToMany с составным ключом
Отвратительный твист состоит в том, что Comment
имеет составной ключ, включая внешний ключ, до Post
из-за существующего дизайна базы данных. Следовательно, я не мог найти способ, чтобы внешний ключ был частью составного ключа в Comment
без двунаправленной связи, хотя мне не нужно двунаправленное отношение.
Классы выглядеть следующим образом с Ломбок аннотаций:
@Entity
@Data
public class Post {
@Id
@GeneratedValue
private long id;
@OneToMany(mappedBy = "post", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
private Set<Comment> comments = new HashSet<>();
private String title;
}
А Комментарий:
@Entity
@IdClass(Comment.CommentPk.class)
@Data
@EqualsAndHashCode(exclude = "post")
@ToString(exclude = "post")
public class Comment {
@Id
private long id;
@Id
@ManyToOne(fetch = FetchType.LAZY)
@RestResource(exported = false)
@JsonIgnore
private Post post;
private String content;
@Data
static class CommentPk implements Serializable {
private long id;
private Post post;
}
}
И репозиторий:
public interface PostRepository extends JpaRepository<Post, Long> {
}
Если я пытаюсь создать Post
с Comment
, произойдет исключение, которое POST_ID
не может быть NULL. Другими словами, он не имеет обратной ссылки на родителя Post
в Comment
, который он пытается сохранить.
Это может быть решена путем добавления метода @PrePersist
к Post
, который поддерживает эту обратную ссылку:
@PrePersist
private void maintainParentBackreference() {
for (Comment comment : this.comments) {
comment.setPost(this);
}
}
выше прекрасно работает при создании нового Post
, но это не помогает при попытке добавить Comment
к существующей Post
(например, с помощью запроса PUT), потому что следующая ошибка возникает при попытке вставить комментарий:
NULL not allowed for column "POST_ID"; SQL statement:
insert into comment (content, id, post_id) values (?, ?, ?) [23502-193]
Напомним, что шаги, чтобы Repro дуче являются:
- опубликовать
Post
без каких-либоComment
сек - PUT к созданному
Post
сComment
Что такое простейший способ, которым я могу достичь возможность обновить/добавить Comment
s до существующего Post
с использованием Spring Data REST?
образец проект, который демонстрирует это можно найти здесь: https://github.com/shakuzen/aggregate-child-update-sample/tree/composite-key
Эта конкретная установка в composite-key
ветви репозитория.Для того, чтобы воспроизвести описанную выше неудачу с этим кодом, вы можете следить за действия вручную воспроизведение в README или запустить тест интеграции AggregateCompositeKeyUpdateTests.canAddCommentWithPut
Благодарим вас за углубленный отклик. Я был бы рад сделать то, что вы предлагаете, если бы я мог легко использовать Spring Data REST, используя эти методы при обработке соответствующих HTTP-запросов, но я не уверен, как лучше всего это сделать. –
Добавлена информация о том, как интегрировать мою идею с Spring Data REST с помощью прослушивателя или аннотированных обратных вызовов обработчика. – Naros