Переопределить функцию delete() в Grails Domain-Class

У меня есть следующие классы:

class User {
 String name
}

class Book {
  User user
}

Я хочу, чтобы при удалении объекта «Пользователь» также удалялся объект «Книга», содержащий экземпляр пользователя. Так как я не имею отношения от класса User к классу книги, то каскадное удаление не пройдет.

Я могу написать класс Book как:

class Book {
  belongsTo = [user: User]
}

Первый также не выполняет каскадное удаление, потому что в классе User все еще не определено отношение.

Я сделал следующее:

class User {
 String name

 def deleteUser() {
   def books = Book.findAllByUser(this)
   books.each { it.delete(flush: true) }
 }
 delete(flush: true)
}

Не думаю, что это лучшее решение. Что я могу сделать вместо этого? Есть ли способ как-то расширить функцию удаления() класса User?

Я пробовал следующее, но это не удалось.

 def delete() {
   def books = Book.findAllByUser(this)
   books.each { it.delete(flush: true) }
 }
 super.delete(flush: true)

person confile    schedule 28.10.2013    source источник


Ответы (1)


Именно здесь бизнес-логика встречается с транзакциями внутри класса Service. Вот как бы я это сделал, если бы использовал отношение, как вы его определили:

def UserService {

  static transactional = true

  def delete(Long userId) {
      def user = User.get(userId)
      def userBooks = Book.findAllByUser(user)
      userBooks*.delete()
      user.delete()
  }

}

А потом просто вызвать этот сервис с контроллера.

Возможно, если книга действительно принадлежит пользователю, определите обе стороны отношений, и они должны каскадироваться.

person Gregg    schedule 28.10.2013
comment
Вы бы использовали удаление (flush: true) или без сброса? Почему бы вам не использовать этот метод в модели? - person confile; 28.10.2013
comment
Обычно я не использую флеш при обработке транзакции. Особенно, когда манипулируют несколькими доменами. Я не добавляю его в модель, потому что мне нужен контроль над транзакциями, и я не большой поклонник такой бизнес-логики внутри модели. - person Gregg; 28.10.2013
comment
Под транзакционным контролем вы подразумеваете, что все происходит внутри одной транзакции? В модели это невозможно? - person confile; 28.10.2013
comment
Я думаю, что службы являются транзакционными = true по умолчанию? - person confile; 28.10.2013
comment
Честно говоря, я не знаю, как транзакции работают внутри модели (домена). Я знаю, как они работают с сервисами, поэтому я предложил разместить вашу бизнес-логику внутри сервиса. Честно говоря, я думаю, что если вы сделаете отношения двунаправленными, вы сделаете свою жизнь намного проще. Все, что вам нужно сделать, это удалить пользователя, удаление книги будет каскадным. Если это то поведение, которое вам нужно. - person Gregg; 28.10.2013
comment
Что ж, вы правы, но рассмотрим случай, когда у пользователя может быть от 0 до 1 книг, а книга может содержать от 0 до n пользователей. Вы не можете установить принадлежности к классу User, потому что пользователь не должен быть удален при удалении книги. Любая идея для этого? - person confile; 29.10.2013
comment
Просто правильно определите свои отношения в своих доменах и позвольте GORM справиться с такими вещами за вас. То, о чем вы сейчас говорите, — это «многие ко многим». Если у вас есть новый вопрос, задайте новый вопрос. Лучше, чем вести беседы в комментариях. - person Gregg; 29.10.2013
comment
Вот вопрос: stackoverflow.com/questions/19665316/ - person confile; 29.10.2013