Подтвердить что ты не робот

Ошибка удаления гибернации: пакетное обновление возвращено Неожиданное количество строк

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

Класс MemberDao

public static void deleteMember(Member member) {
    Session hibernateSession = HibernateUtil.getSessionFactory().getCurrentSession();
    Transaction tx = hibernateSession.beginTransaction();
    hibernateSession.delete(member);
    tx.commit();
}

Контрольная часть

if(delete != null) {
    HttpSession httpSession = request.getSession();
    Member member = (Member) httpSession.getAttribute("member");

    MemberDao.deleteMember(member);

    nextPage = "ledenlijst.jsp";
}

Состояние HTTP 500

org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1

Иногда это даже вызывает эту ошибку, когда я пытаюсь выполнить страницу несколько раз.

org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update

Кто-нибудь знает, что именно вызывает эти ошибки?

4b9b3361

Ответ 1

Ошибка может быть вызвана несколькими вещами. Я не беру на себя ответственность за это, нашел здесь.

  • Промывка данных перед фиксацией объекта может привести к очистке всех объект, ожидающий сохранения.
  • Если объект имеет первичный ключ, который автоматически генерируется, и вы принудительно назначенный ключ
  • если вы очищаете объект перед тем, как передать объект базы данных.
  • Нулевой или неправильный идентификатор: если вы установили идентификатор в ноль или что-то еще, Hibernate будет пытаться обновить вместо вставки.
  • Объект Stale: Hibernate кэширует объекты из сеанса. Если объект был изменен, и Hibernate не знает об этом, он будет бросить это исключение - обратите внимание на StaleStateException

Также посмотрите этот ответ beny23, в котором содержится несколько дополнительных советов, чтобы найти проблему.

  • В вашей конфигурации спящего режима установите для hibernate.show_sql значение true. Это должно показать вам SQL, который выполняется и вызывает проблему.
  • Задайте уровни журналов для Spring и Hibernate для DEBUG, это даст вам более полное представление о том, какая строка вызывает проблему.
  • Создайте unit test, который реплицирует проблему без настройки диспетчера транзакций в Spring. Это должно дать вам лучшее представление о нарушении кода.

Ответ 2

Исключение org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1 использовать, чтобы быть брошенным, когда Hibernate заметил, что объект, который он хочет сбросить в базу данных, не совсем так, как это было в начале транзакции.

Я подробно описал два разных варианта использования, которые происходят со мной здесь.

Ответ 3

В моем случае это исключение было вызвано неправильным сопоставлением объектов. Касади для отношения не было, и связанный дочерний объект не был сохранен, прежде чем пытаться ссылаться на него от родителя. Изменение его на

    @OneToMany(cascade = CascadeType.ALL)

исправлена ​​проблема.

Разумеется, лучший способ найти причину этого исключения - установить show_sql и уровень DEBUG для журналов - он остановится только на sql, который вызвал проблему.

Ответ 4

Я столкнулся с такой же проблемой. Код работал в тестовой среде. Но он не работал в промежуточной среде.

org.hibernate.jdbc.BatchedTooManyRowsAffectedException: Batch update returned unexpected row count from update [0]; actual row count: 3; expected: 1

Проблема заключалась в том, что в таблице была одна запись для каждого первичного ключа при тестировании таблицы БД. Но в промежуточной БД было несколько записей для того же первичного ключа. (Проблема заключается в промежуточном БД, в таблице не было ограничений первичного ключа, также было несколько записей.)

Поэтому каждый раз при обновлении он получает сбой. Он пытается обновить одну запись и ожидать, что количество обновлений будет равным 1. Но поскольку в таблице для одного и того же первичного ключа было 3 записи, число результатов обновления результата 3. Поскольку ожидаемое количество обновлений и фактический результат обновления не совпадают, Он выдает исключение и откатывается.

После того, как я удалил все записи, которые имеют дублирующий первичный ключ и добавили ограничения первичного ключа. Он работает нормально.

Ответ 5

это решение для моего дела, возможно, это поможет вам!

На самом деле это была проблема преобразования между типом поля базы данных (timestamp on postgreSQL) и его эквивалентным типом свойств (Calendar) в файле hibernate xml. Когда Hibernate выполнил этот запрос на обновление, он не извлекал строку, потому что запрос запрашивал с плохим преобразованием значения календаря. Поэтому я просто заменил тип свойства "Календарь" в "Дата" в файле Hibernate xml и проблема была исправлена.

Ответ 6

Я недавно испытал это, и произошло то, что я использовал метод обновления, и он выбрасывал исключение, потому что не было существующей записи. Я изменил метод saveOrUpdate. Это сработало.

Ответ 7

У меня возникла такая же проблема с hibernate/JPA 2.1 при использовании memcached в качестве вторичного кеша. Вы получите исключение выше, а также исключение StaleStateException. Резолюция была иной, чем было отмечено ранее.

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

Решение состоит в том, чтобы просто быть более эффективным. Вместо того, чтобы чередовать в цикле, попытайтесь решить, какие элементы нужно читать и делать это, желательно в одну операцию. Затем выполните удаление в отдельной операции. Опять же, все в одной и той же транзакции, но не перебирайте спящий режим с помощью операций чтения/удаления/чтения/удаления.

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

Ответ 8

У меня была эта проблема,

Я проверил свой код, проблем не было, но когда я проверил свои данные, я обнаружил, что у меня было два объекта с одним и тем же идентификатором!

Итак, flush() не может работать, потому что он работает один за другим для пакетных обновлений и обнаружил 2 строки. Поэтому он не обновлял и не вводил исключение, но это была моя проблема. Я не знаю, хорошо ли это для вас или нет!