Spring / Hibernate / JPA: предотвращение переназначения дочернего элемента другому родителю. - PullRequest
1 голос
/ 03 февраля 2020

Я работаю в приложении SpringBoot с Hibernate, предоставляющим интерфейс REST.

Проблема

Пользователи могут создавать объекты, назовем их parent. Пользователи могут связать объект parent с несколькими элементами child. Эти элементы также состоят из других объектов, но давайте пока будем проще. Я хочу предотвратить случай, когда клиент может сделать следующее:

  • создать parent1 и создать child1, child2
  • создать parent2 и создать child3
  • обновление parent1 с child3 в полезной нагрузке

Такое поведение не должно быть возможным, поскольку элементы child не должны обновляться, если они принадлежат другому родителю. Моя цель - сделать невозможным обновление parent и обновление child, принадлежащее другой parent.

модели

@Entity(name = "Parent")
@Table(name = "t_parent")
data class Parent(

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    val id: Int = 0,

    @JoinColumn(name = "fk_parent")
    @OneToMany(orphanRemoval = true, cascade = [CascadeType.ALL])
    val children: MutableList<Child> = mutableListOf()
)

@Table(name = "t_child")
@Entity(name = "Child")
data class Child(

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    val id: Int = 0,
)

Я использую Spring JpaRepository для обеспечения устойчивости.

Решения?

Самый глупый способ сделать это - извлечь parent1 из базы данных и удалить все child элементы из запроса клиента, которые не содержатся в dbParent1. Думаю, это довольно утомительно и не очень умно.

Спасибо за ваш совет.

Ответы [ 2 ]

0 голосов
/ 03 февраля 2020

Я бы сделал это следующим образом для операции обновления:

1) Получите родителя с помощью childId

2a) Если нет родителей, просто добавьте ребенка к родителю (новый дочерний элемент)

2b) В противном случае проверьте, принадлежит ли дочерний элемент родительскому элементу (возможно, вы можете использовать parentId, установленный в @PathVariable

2b1). Если нет, бросьте new IllegalArgumentException("wrong parent")

2b2) В противном случае обновите родительский элемент

0 голосов
/ 03 февраля 2020

А как насчет транзакций? В транзакционном методе вы можете проверить, принадлежит ли ребенок другому родителю. Если вы обнаружите какие-либо препятствия для обновления / вставки или чего-либо еще, откатите транзакцию (например, просто сгенерируйте исключение). Эта методология потребует дополнительного уровня обслуживания в вашей архитектуре, поскольку код репозиториев автоматически генерируется из объявлений интерфейса. Этот подход описан здесь: Как переопределить метод сохранения CrudRepository REST мудро

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...