Проблема дублирования транзакций в спящем режиме - PullRequest
3 голосов
/ 01 августа 2009

Я хочу обновить часть своей таблицы в базе данных и хочу, чтобы все эти операции выполнялись за 1 транзакцию, прежде всего я удаляю какую-то запись в branchbuildin (таблица) и вставляю новую после этого действия Проблема возникла, когда я вставляю и вхожу с одинаковым именем здания и branch_fk (потому что у меня есть это ограничение для этой таблицы (uniqueConstraints = {@ UniqueConstraint (columnNames = {"buildingname", "branch_fk"})})), но когда t использовать сеанс гибернации и использовать обычную транзакцию JDBC. У меня нет этих проблем.

List<Integer> allBranchBuilding = branchBuildingDao.getAllBranchBuildingID(pkId, sess);
            for (Integer integer : allBranchBuilding) {
                branchBuildingDao.delete(integer, sess); // delete kardane tamame BranchBuilding ha va tel haie aanha
            }

            Address myAdr = new Address();
            setAddress(myAdr, centralFlag, city, latit, longit, mainstreet, remainAdr, state);
            BranchBuildingEntity bbe = new BranchBuildingEntity();
            setBranchBuildingEntity(bbe, be, myAdr, city, centralFlag, latit, longit, mainstreet, buildingName, remainAdr, state, des);
            branchBuildingDao.save(bbe, sess);//Exception Occurred                

Я получаю мой сеанс первым из метода:

        Session sess = null;
        sess = HibernateUtil.getSession();
        Transaction tx = sess.beginTransaction();

1 Ответ

6 голосов
/ 01 августа 2009

Вы правы, все происходит в одной транзакции и в одном и том же сеансе Hibernate.

Сессия отслеживает каждую сущность, которой она управляет. Даже если вы попросили удалить его в базе данных, соответствующий объект все еще запоминается в сеансе до его завершения.

В общем, возможно, что Hibernate переупорядочивает ваши операции при отправке их в базу данных, для причины эффективности.

Что вы могли бы сделать, это сбросить (т.е. отправить в базу данных) вашу транзакцию, поскольку при сохранении (при необходимости вы также можете очистить, т. Е. Очистить объекты, запомненные сеансом, - после сброса):

sess.flush();
// sess.clear(); // if needed or convenient for you
branchBuildingDao.save(bbe, sess);

Также обратите внимание, что, пока ваши сущности запоминаются сессией, их изменение приведет к автоматическому обновлению при закрытии сессии.

В нашем проекте у нас есть метод, который эффективно удаляет коллекцию (и еще один для массива, объявленного с использованием удобного синтаксиса параметра ...) сущностей (он работает для всех сущностей, этого не нужно делать для каждой сущности), удалив их из сеанса одновременно и позаботившись о сбрасывании до:

  1. Цикл для всех объектов, удалить его (используя sess.delete(e)) и добавить его в список «удаленных».
  2. Каждые 50 объектов (соответствующих размеру пакета, который мы настроили для повышения эффективности) (и в конце):
    • сбросить сеанс, чтобы Hibernate немедленно отправил изменения в базу данных,
    • цикл в списке «удаленных», очистить каждую сущность от сеанса (используя sess.evict(e)).
    • очистить список удаленных пользователей.

Не волнуйтесь, flush только отправляет SQL в базу данных. Он все еще подлежит фиксации или откату.

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