JPA + Hiberante, как удалить объекты на нескольких зависимостях - PullRequest
0 голосов
/ 09 сентября 2018

У меня есть класс User, класс Conversation и класс Message. Пользователь может быть отправителем и получателем. Я не знаю, как настроить Каскадные типы, если мои цели:

  • если пользователь удален, сохранить его / ее сообщения и его / ее разговоры
  • если оба пользователя удалены, удалите беседу и сообщения
  • если пользователь удаляет свое последнее сообщение из беседы, продолжайте беседу с сообщением других пользователей
  • если пользователь удаляет беседу, удаляет только пользователя из беседы, но сохраняет сам разговор и другого пользователя со всеми сообщениями
  • сразу после удаления обоих пользователей удалить беседы без пользователей и сообщения для этих бесед

Мне кажется, я могу установить все CascadeType, кроме CascadeType. Удалять везде. Я должен проверить каждую удаление вручную. Я думаю, что не могу установить CascadeType.Delete, например, для сообщений пользователя, потому что я хочу сохранить их, даже удаляя пользователя, и удаляю их, только если я удаляю всех участников разговора. Я не уверен, но думаю, что не могу установить orphanremoval в сообщении пользователя, потому что, если я удаляю пользователя, он очищает список сообщений и удаляет сообщения.

@Entity
class User {

    @Id
    @GeneratedValue
    val id: Long = 0

    @OneToMany(mappedBy = "reviewer")
    lateinit var conversations: List<Conversation>

    @OneToMany(mappedBy = "sender")
    lateinit var sentMessages: List<Message>

    @OneToMany(mappedBy = "receiver")
    lateinit var receivedMessages: List<Message>
}

@Entity
class Conversation {

    @Id
    @GeneratedValue
    val id: Long = 0

    @OneToMany(mappedBy = "conversation")
    lateinit var messages: List<Message>
}


@Entity
class Message {

    @Id
    @GeneratedValue
    val id: Long = 0

    @ManyToOne
    lateinit var conversation: Conversation

    @ManyToOne
    lateinit var sender: User

    @ManyToOne
    lateinit var receiver: User

    lateinit var message: String
}

1 Ответ

0 голосов
/ 10 сентября 2018

Установленные вами нетривиальные правила слишком сложны для Hibernate, чтобы их можно было обрабатывать «из коробки».

Я рекомендую использовать концепцию DDD Агрегаты и Агрегатные корни, чтобы разложить вашу модель, использовать каскад внутри Агрегатов и общаться с событиями между ними.

Я вижу два агрегата: User и Conversation. Агрегат Conversation состоит из Conversation в качестве корневого агрегата и Message s в качестве дополнительных объектов.

Удалите список Message s из User и предоставьте вместо него методы поиска в ConversationRepository.

Вся логика, которую вы описываете, заключается в методах User, UserRepository, Conversation и ConversationRepository. Классы User* могут делегироваться ConversationRepository для манипулирования Conversation s и Message s.

При таком подходе реализация желаемой логики должна быть проще для реализации, тестирования и понимания. Многие шаги могут быть проще (и, возможно, быстрее) реализованы с использованием прямого SQL вместо JPA. Конечно, вам нужно позаботиться о том, чтобы JPA-кэш 1-го уровня не устаревал.

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