Я получаю следующую ошибку гибернации. Я могу определить функцию, которая вызывает проблему. К сожалению, в этой функции есть несколько вызовов БД. Я не могу найти строку, которая вызывает проблему, поскольку hibernate завершает сеанс в конце транзакции. Приведенная ниже ошибка гибернации выглядит как общая ошибка. Это даже не упомянуло, какой Бин вызывает проблему. Кто-нибудь знаком с этой ошибкой гибернации?
org.hibernate.StaleStateException: Batch update returned unexpected row count from update: 0 actual row count: 0 expected: 1
at org.hibernate.jdbc.BatchingBatcher.checkRowCount(BatchingBatcher.java:93)
at org.hibernate.jdbc.BatchingBatcher.checkRowCounts(BatchingBatcher.java:79)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:58)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:195)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:235)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:142)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:297)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:985)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:333)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:584)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransacti
onManager.java:500)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManag
er.java:473)
at org.springframework.transaction.interceptor.TransactionAspectSupport.doCommitTransactionAfterReturning(Transaction
AspectSupport.java:267)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:176)
Ответы:
Без кода и сопоставлений для ваших транзакций практически невозможно исследовать проблему.
Однако, чтобы лучше понять причину проблемы, попробуйте следующее:
Надеюсь, это поможет.
источник
Я получил то же исключение при удалении записи по идентификатору, который вообще не существует. Так что проверьте, что запись, которую вы обновляете / удаляете, действительно существует в БД
источник
Решение. В файле отображения Hibernate для свойства id, если вы используете какой-либо класс генератора, для этого свойства не следует явно устанавливать значение с помощью метода setter.
Если вы установите значение свойства Id явно, это приведет к ошибке выше. Отметьте это, чтобы избежать этой ошибки. или это ошибка, когда вы указываете в файле отображения поле generator = "native" или "incremental", и в вашей DATABASE отображаемая таблица не является auto_incremented Решение: перейдите в свою DATABASE и обновите таблицу, чтобы установить auto_increment
источник
Это случилось со мной однажды случайно, когда я назначал определенные идентификаторы некоторым объектам (тестирование), а затем пытался сохранить их в базе данных. Проблема заключалась в том, что в базе данных существовала специальная политика для установки идентификаторов объектов. Только не назначайте идентификатор, если у вас есть политика на уровне Hibernate.
источник
В моем случае я пришел к этому исключению в двух похожих случаях:
@Transactional
меня был вызов к другому сервису (с долгим временем ответа). Метод обновляет некоторые свойства объекта (после метода объект все еще существует в базе данных). Если пользователь дважды запрашивает метод (поскольку он считает, что он не работает в первый раз) при выходе из транзакционного метода во второй раз, Hibernate пытается обновить сущность, которая уже изменила свое состояние с начала транзакции. Когда Hibernate выполняет поиск сущности в состоянии и обнаруживает ту же сущность, но уже измененную первым запросом, он выдает исключение, поскольку не может обновить сущность. Это как конфликт в GIT.Вывод: в моем случае это не было проблемой, которую можно найти в коде. Это исключение выдается, когда Hibernate обнаруживает, что объект, впервые выбранный из базы данных, изменился во время текущей транзакции , поэтому он не может сбросить его в базу данных, поскольку Hibernate не знает, какая версия объекта является правильной: текущей выборка транзакции в начале; или тот, который уже хранится в базе данных.
Решение: чтобы решить проблему, вам придется поиграть с Hibernate LockMode, чтобы найти тот, который наилучшим образом соответствует вашим требованиям.
источник
LockMode.READ
илиLockMode.OPTIMISTIC
.Я только столкнулся с этой проблемой и обнаружил, что я удаляю запись и пытаюсь обновить ее впоследствии в транзакции Hibernate.
источник
Это может произойти, когда триггер (-ы) выполняют дополнительные запросы DML (изменение данных), которые влияют на количество строк. Моим решением было добавить следующее в верхней части моего триггера:
источник
Я столкнулся с той же проблемой. Код работал в среде тестирования. Но это не работало в сценической среде.
Проблема заключалась в том, что таблица имела одну запись для каждого первичного ключа в тестируемой таблице БД. Но в промежуточной БД было несколько записей для одного и того же первичного ключа. (Проблема в том, что в промежуточной БД для таблицы не было ограничений первичного ключа, а также было несколько записей.)
Таким образом, каждый раз при обновлении происходит сбой. Он пытается обновить одну запись и рассчитывает получить количество обновлений равным 1. Но поскольку в таблице было 3 записи для одного и того же первичного ключа, число обновлений результата находит 3. Поскольку ожидаемое количество обновлений и фактическое число обновлений результатов не совпадают Выдает исключение и откатывается.
После я удалил все записи, которые имеют дубликаты первичного ключа и добавил ограничения первичного ключа. Работает нормально.
фактическое количество строк: 0 // означает, что запись не найдена для обновления
update: 0 // означает, что запись не найдена, поэтому обновление не
ожидается: 1 // означает, что ожидается как минимум 1 запись с ключом в таблице базы данных.
Здесь проблема в том, что запрос пытается обновить запись для некоторого ключа, но hibernate не нашел ни одной записи с ключом.
источник
Как говорит Юлиус, это происходит, когда обновление происходит на объекте, дочерние элементы которого удаляются. (Вероятно, потому, что было необходимо обновление для всего Объекта Отца, и иногда мы предпочитаем удалить детей и повторно вставить их в Отца (новое, старое не имеет значения) вместе с любыми другими обновлениями, которые отец может иметь в любом из другие его простые поля) Итак ... для того, чтобы это работало, удалите дочерние элементы (внутри транзакции), вызвав
childrenList.clear()
(Не перебирайте дочерние элементы и удаляйте каждый с некоторымиchildDAO.delete(childrenList.get(i).delete()))
и устанавливая@OneToMany(cascade = CascadeType.XXX ,orphanRemoval=true)
на стороне отца объекта. Затем обновите отца (папа DAO.update (папа)). (Повторите эти действия для каждого объекта отца). В результате у детей обрывается связь с отцом, а затем они удаляются из системы как сироты.источник
Я столкнулся с этой проблемой, когда у нас были отношения один-много.
В файл отображения hibernate hbm для мастера, для объекта с заданным типом расположения, добавлено,
cascade="save-update"
и он работал нормально.Без этого hibernate по умолчанию пытается обновить несуществующую запись и вместо этого вставляет.
источник
Это также может произойти , когда вы пытаетесь
UPDATE
с PRIMARY KEY .источник
Я получил ту же проблему, и я убедился, что это может произойти из-за автоматического увеличения первичного ключа. Для решения этой проблемы не вставляйте значение автоинкремента с набором данных. Вставьте данные без первичного ключа.
источник
Другой способ получить эту ошибку, если у вас есть нулевой элемент в коллекции.
источник
это происходит, когда вы пытаетесь удалить тот же объект, а затем снова обновить тот же объект, используйте это после удаления
session.clear ();
источник
Это также случилось со мной, потому что у меня был свой идентификатор как Long, и я получал из представления значение 0, и когда я попытался сохранить в базе данных, я получил эту ошибку, затем я исправил ее, установив id в ноль.
источник
Я столкнулся с этой проблемой, когда вручную начинал и совершал транзакции внутри метода, помеченного как
@Transactional
. Я исправил проблему, обнаружив, существует ли активная транзакция.Затем я позволил Spring обработать транзакцию.
источник
Это происходит, когда вы объявили управляемый компонент JSF как
когда вы должны объявить как
С уважением;
источник
Я получил эту ошибку при попытке обновить объект с идентификатором, который не существует в базе данных. Причиной моей ошибки было то, что я вручную назначил свойство с именем 'id' для JSON-представления объекта на стороне клиента, а затем при десериализации объекта на стороне сервера это свойство 'id' перезаписывало бы переменную экземпляра ( также называемый «id»), который должен был генерировать Hibernate. Поэтому будьте осторожны с именами коллизий, если вы используете Hibernate для генерации идентификаторов.
источник
Я также столкнулся с той же проблемой. В моем случае я обновлял объект, который даже не существовал, используя
hibernateTemplate
.На самом деле в моем приложении я получал объект БД для обновления. И, обновляя его значения, я также по ошибке обновил его идентификатор, продолжил его обновление и столкнулся с упомянутой ошибкой.
Я использую
hibernateTemplate
для операций CRUD.источник
После прочтения всех ответов не нашел никого, кто мог бы поговорить об обратном атрибуте hibernate.
По моему мнению, вы также должны проверить в ваших отношениях, правильно ли задано обратное ключевое слово. Ключевое слово Inverse создается, чтобы определить, какая сторона является владельцем для поддержания отношений. Процедура обновления и вставки зависит от этого атрибута.
Предположим, у нас есть две таблицы:
principal_table , middle_table
с отношением одного ко многим . Классы отображения спящего режима - Главный и Средний соответственно.
Таким образом, у класса Principal есть набор объектов Middle . Файл отображения xml должен выглядеть следующим образом:
Поскольку для параметра инверсии задано значение «истина», это означает, что «средний» класс является владельцем отношения, поэтому основной класс НЕ ОБНОВЛЯЕТ отношение.
Таким образом, процедура обновления может быть реализована так:
Это сработало для меня, но вы можете предложить несколько выпусков, чтобы улучшить решение. Таким образом, мы все будем учиться.
источник
В нашем случае мы наконец выяснили причину возникновения StaleStateException.
Фактически мы удаляли строку дважды в одном сеансе гибернации. Ранее мы использовали ojdbc6 lib, и в этой версии это было нормально.
Но когда мы обновились до odjc7 или ojdbc8, удаление записей дважды было исключением. В нашем коде была ошибка, из-за которой мы дважды удаляли, но в ojdbc6 это было неочевидно.
Мы смогли воспроизвести этот фрагмент кода:
При первом сбросе гибернация идет и вносит изменения в базу данных. Во время 2-го сброса hibernate сравнивает объект сеанса с фактической записью таблицы, но не может найти один, следовательно, исключение.
источник
Эта проблема в основном возникает, когда мы пытаемся сохранить или обновить объект, который уже загружен в память при запущенном сеансе. Если вы извлекли объект из сеанса и пытаетесь обновить его в базе данных, это исключение может быть сгенерировано.
Я использовал session.evict (); чтобы сначала удалить кэш, хранящийся в спящем режиме, или, если вы не хотите рисковать потерей данных, лучше создать другой объект для хранения временных данных.
источник
Hibernate 5.4.1 и выпуск HHH-12878
До Hibernate 5.4.1 исключения сбоя оптимистической блокировки (например,
StaleStateException
илиOptimisticLockException
) не включали оператор сбоя.Проблема HHH-12878 была создана для улучшения Hibernate, чтобы при создании исключения оптимистической блокировки
PreparedStatement
также регистрировалась реализация JDBC :Время тестирования
Во-первых, мы определим
Post
сущность, которая определяет@Version
свойство, следовательно, задействуя механизм неявной оптимистической блокировки :Мы включим пакетирование JDBC, используя следующие 3 свойства конфигурации:
Мы собираемся создать 3
Post
объекта:И Hibernate выполнит пакетную вставку JDBC:
Итак, мы знаем, что пакетная обработка JDBC работает просто отлично.
Теперь давайте повторим проблему с оптимистической блокировкой:
Первая транзакция выбирает все
Post
объекты и изменяетtitle
свойства.Однако, прежде чем первый
EntityManager
будет сброшен, мы собираемся выполнить второй переход, используяexecuteSync
метод.Вторая транзакция изменяет первую
Post
, поэтому онаversion
будет увеличиваться:Теперь, когда первая транзакция попытается
EntityManager
сбросить, мы получимOptimisticLockException
:Итак, вам нужно перейти на Hibernate 5.4.1 или новее, чтобы воспользоваться этим улучшением.
источник
Это произошло, если вы изменили что-то в наборе данных, используя собственный SQL-запрос, но постоянный объект для того же набора данных присутствует в кеше сеанса. Используйте session.evict (yourObject);
источник
Hibernate кэширует объекты из сеанса. Если объект доступен и изменен более чем
org.hibernate.StaleStateException
одним пользователем, он может быть брошен. Это может быть решено с помощью метода слияния / обновления объекта перед сохранением или использованием блокировки. Дополнительная информация: http://java-fp.blogspot.lt/2011/09/orghibernatestalestateexception-batch.htmlисточник
Один из случаев
источник
Я столкнулся с этим исключением, и Hibernate работал хорошо. Я попытался вручную вставить одну запись с помощью pgAdmin, здесь проблема стала ясной. Запрос SQL вставки возвращает 0 вставки. и есть триггерная функция, которая вызывает эту проблему, потому что она возвращает ноль. поэтому я должен только установить его, чтобы вернуть новый. и наконец я решил проблему.
надеюсь, что это поможет любому телу.
источник
Я получил эту ошибку, потому что я по ошибке сопоставил
ID
столбец, используяId(x => x.Id, "id").GeneratedBy.**Assigned**();
Проблема решена с помощью
Id(x => x.Id, "id").GeneratedBy.**Identity**();
источник
Это происходит со мной, потому что я пропускаю объявление идентификатора в классе бина.
источник
В моем случае была проблема с базой данных, так как один из сохраненных процессов потреблял весь процессор, вызывая большое время отклика БД. Как только это было убито, проблема была решена.
источник