Hibernate удалить объекты на каскаде - PullRequest
4 голосов
/ 15 сентября 2010

Я немного запутался в том, как работает каскад = "delete". Я определил отображение следующим образом в файле отображения города:

<set inverse="true" name="client" cascade="delete">
  <key>
    <column name="id_name"/>
  </key>
    <one-to-many class="model.Client"/>
 </set>

Клиент класса имеет внешний ключ для класса City.

Итак, когда я бегу:

List object = null;
try {
   org.hibernate.Transaction tx = session.beginTransaction();
   try {
       session.delete("from City where row_id=" + row_id and table_id = " + table_id);
   } catch (Exception e) {
       e.printStackTrace();
   }
}

Должны ли все клиенты также быть удалены или я должен как-то с этим справиться? Правильно ли я передаю запрос как параметр метода методу delete () сеанса? Спасибо за любую помощь. С уважением, дерзость.

Ответы [ 2 ]

7 голосов
/ 15 сентября 2010

Я немного озадачен тем, как работает каскад = "delete" (...)

Каскадирование операции delete означает, что если вы delete родитель, операция будет распространяться по ассоциации.Таким образом, в вашем случае удаление объекта City должно распространяться на Client s.

Так что, когда я запускаю (...) Должны ли все клиенты также быть удалены

Метод Session#delete(String), который принимает строку запроса HQL , выполняет ее, выполняет итерацию результатов и вызывает Session#delete(Object) для каждого объекта с учетом каскадирования (поэтому клиенты будут удалены, если вашзапрос на самом деле является запросом HQL).

Но этот метод старый и устарел в Hibernate 3 (и перешел на «классический» интерфейс Session), я не очень рекомендую его (он выполняет 1+ N операций и довольно неэффективно для удаления огромного количества результатов).

Если это проблема, предпочтите поддержку массового удаления , предлагаемую Hibernate:

int deleteCount = session.createQuery("delete from Foo where bar = :bar") 
    .setParameter("bar", bar);
    .executeUpdate()

Но обратите внимание, что массовое удаление имеет ограничения:

  • Вы не можете использовать псевдонимы.
  • Нет внутренних объединений в запросе (хотя вы можете использовать подвыборы в предложении where).
  • A массовое удаление не каскадно (и не позаботится о соединении таблиц).

Так что при массовом удалении вам придется удалить Client до City.Но производительность намного лучше.

PS: В какой-то момент вам нужно commit() (а также улучшить обработку ошибок, например, rollback() в блоке catch)

Ссылки

0 голосов
/ 15 сентября 2010
  1. Если вы удалите город, все клиенты также будут удалены. Если вы удалите клиента, город останется один.

  2. session.delete() нельзя вызвать с помощью запроса HQL. Вы должны передать один город для удаления.

Кроме того, вы можете использовать session.createSQLQuery() для создания оператора удаления. Это позволяет вам удалить много городов за один раз. Недостаток этого метода заключается в том, что вы должны удалить клиентов самостоятельно и , очистить кеш (Hibernate не пытается понять, что может означать ваш запрос).

...