Hibernate - Пакетное обновление вернуло неожиданное количество строк из обновления: 0 фактическое количество строк: 0 ожидается: 1

141

Я получаю следующую ошибку гибернации. Я могу определить функцию, которая вызывает проблему. К сожалению, в этой функции есть несколько вызовов БД. Я не могу найти строку, которая вызывает проблему, поскольку 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)
Sujee
источник
Спасибо @ Питер Мортенсен. Я обновил свою электронную почту.
Суджи
У меня та же проблема. Это не большая проблема, так как это происходит очень редко. Использование show_sql нецелесообразно, поскольку для воспроизведения этого поведения требуются миллионы транзакций. Однако из-за того, что это происходит неоднократно во время системного теста, который я запускаю (с несколькими транзакциями), я подозреваю, что есть определенная причина.
daniel_or_else
Я столкнулся с этой проблемой , пока я пытался обновить строки , которые имеют NO изменений. Не обновляйте что-либо, если нет разницы.
пятнадцатое

Ответы:

62

Без кода и сопоставлений для ваших транзакций практически невозможно исследовать проблему.

Однако, чтобы лучше понять причину проблемы, попробуйте следующее:

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

Надеюсь, это поможет.

beny23
источник
21
hibernate.show_sql> Я бы посоветовал установить для категории журнала уровень org.hibernate.SQL на DEBUG. Таким образом, вам не нужно изменять конфигурацию спящего режима только для регистрации.
Тьерри
Использование "show_sql" может быть очень многословным и неосуществимым в производстве. Для этого я изменил предложение catch в строке 74 класса BatchingBatcher, чтобы напечатать оператор с помощью ps.toString (), чтобы иметь только оператор, имеющий проблему.
Орден
71

Я получил то же исключение при удалении записи по идентификатору, который вообще не существует. Так что проверьте, что запись, которую вы обновляете / удаляете, действительно существует в БД

Shreyas
источник
12
У меня была эта проблема, когда я удалил дочерний элемент из отношения родитель-потомок, сохранил родительский (который удаляет дочерний элемент), а затем попытался также удалить дочерний элемент вручную.
Дэйв Тибен
Это решило мою проблему. Запись не существовала, и мой сервис вызывал метод updateAll (), тогда как на самом деле ему нужно было вызвать метод createOrUpdateAll (). Спасибо.
Митал Притмани
3
так как решить проблему? Если я получу запись, а затем удаляю ее; но если система уже удалит его перед тем, как удалить другое, мое приложение сгенерирует исключение.
Стоуни
@ davethieben, это была именно та информация, которая мне была нужна. Я не осознавал, что отношения между родителями и детьми сохраняются при удалении.
снег
Решение состоит в том, чтобы использовать select for update при извлечении записи, чтобы заблокировать строку, чтобы ничто другое не могло удалить ее до вас.
Мэтью Рид
55

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

Если вы установите значение свойства Id явно, это приведет к ошибке выше. Отметьте это, чтобы избежать этой ошибки. или это ошибка, когда вы указываете в файле отображения поле generator = "native" или "incremental", и в вашей DATABASE отображаемая таблица не является auto_incremented Решение: перейдите в свою DATABASE и обновите таблицу, чтобы установить auto_increment

Рида Бирамане
источник
2
Совершенно верно. Это должен быть правильный ответ. Спасибо @ Rēda Biramanē
Kuldeep Verma
1
Тем не менее , вы МОЖЕТЕ установить значение идентификатора на «0», и тогда Hibernate не
стесняется
1
Спасибо! Не уверен, почему это не самый высокий ответ.
Стюарт Макинтайр
18

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

CSN
источник
15

В моем случае я пришел к этому исключению в двух похожих случаях:

  • В методе, помеченном как, у @Transactionalменя был вызов к другому сервису (с долгим временем ответа). Метод обновляет некоторые свойства объекта (после метода объект все еще существует в базе данных). Если пользователь дважды запрашивает метод (поскольку он считает, что он не работает в первый раз) при выходе из транзакционного метода во второй раз, Hibernate пытается обновить сущность, которая уже изменила свое состояние с начала транзакции. Когда Hibernate выполняет поиск сущности в состоянии и обнаруживает ту же сущность, но уже измененную первым запросом, он выдает исключение, поскольку не может обновить сущность. Это как конфликт в GIT.
  • У меня были автоматические запросы (для мониторинга платформы), которые обновляют сущность (и откат вручную через несколько секунд). Но эта платформа уже используется командой тестирования. Когда тестер выполняет тест в том же объекте, что и автоматические запросы (в пределах одной сотой миллисекунды), я получаю исключение. Как и в предыдущем случае, при выходе из второй транзакции ранее извлеченный объект уже изменился.

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

Решение: чтобы решить проблему, вам придется поиграть с Hibernate LockMode, чтобы найти тот, который наилучшим образом соответствует вашим требованиям.

Серхио Лема
источник
Привет, спасибо за ваш полезный ответ. Не могли бы вы сообщить, какой LockMode вы использовали в конце концов, чтобы избавиться от ошибки. Я сталкиваюсь с подобной проблемой, когда API срабатывает последовательно в разные миллисекунды из-за случайного нажатия пользователем дважды. Пессимистичная блокировка снижает производительность; так будет интересно узнать, к чему вы в итоге пошли?
Мадхур Бхайя
1
Прошло много времени с тех пор, как у меня возникла проблема, и я не очень хорошо помню точное решение, которое я нашел, но это было LockMode.READили LockMode.OPTIMISTIC.
Серхио Лема
13

Я только столкнулся с этой проблемой и обнаружил, что я удаляю запись и пытаюсь обновить ее впоследствии в транзакции Hibernate.

Юлий
источник
9

Это может произойти, когда триггер (-ы) выполняют дополнительные запросы DML (изменение данных), которые влияют на количество строк. Моим решением было добавить следующее в верхней части моего триггера:

SET NOCOUNT ON;
Мистер ТА
источник
1
Этот ответ направил меня в правильном направлении. Я работал с устаревшей базой данных, в которой был триггер - к счастью, я заменял то, что делал триггер, кодом, поэтому я мог просто удалить его.
С. Бэгги
2
+1 Это тоже была моя проблема. Я использовал postgresql, поэтому мне нужно было использовать аннотацию @SQLInsert для отключения проверки количества строк: technology-ebay.de/the-teams/mobile-de/blog/…
s1mm0t
ВЫКЛЮЧИТЕ NOCOUNT *
Г. Чардини
7

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

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

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

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

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

Hibernate - Batch update returned unexpected row count from update: 0 actual row count: 0 expected: 1

фактическое количество строк: 0 // означает, что запись не найдена для обновления
update: 0 // означает, что запись не найдена, поэтому обновление не
ожидается: 1 // означает, что ожидается как минимум 1 запись с ключом в таблице базы данных.

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

ParagFlume
источник
Привет @ParagFlume, я получил ту же ошибку "Пакетное обновление вернуло неожиданное количество строк из обновления: 0 фактическое количество строк: 0 ожидается: 1", когда я пытаюсь выбрать один объект из моей базы данных, проблема существует только в любом производстве, есть ли у вас какие-либо Идея о том, как решить эту проблему, я нахожусь в критической ситуации. С уважением !
Джеймс
Я думаю, что запрос не нашел ни одной записи в БД, он ожидает найти одну запись в БД, которую он пытается обновить. Вы можете проверить вручную / query-browser, если запись действительно существует на БД.
ParagFlume
да, запись существует, но моя проблема в том, почему hibernate пытается обновить, я просто использую сервис выбора, чтобы получить объект из базы данных!
Джеймс
может быть, вы пытаетесь изменить состояние объектов. и сессия все еще открыта.
ParagFlume
как я могу проверить это поведение, потому что я не тот человек, который разработал услугу ...
Джеймс
5

Как говорит Юлиус, это происходит, когда обновление происходит на объекте, дочерние элементы которого удаляются. (Вероятно, потому, что было необходимо обновление для всего Объекта Отца, и иногда мы предпочитаем удалить детей и повторно вставить их в Отца (новое, старое не имеет значения) вместе с любыми другими обновлениями, которые отец может иметь в любом из другие его простые поля) Итак ... для того, чтобы это работало, удалите дочерние элементы (внутри транзакции), вызвав childrenList.clear()(Не перебирайте дочерние элементы и удаляйте каждый с некоторыми childDAO.delete(childrenList.get(i).delete()))и устанавливая @OneToMany(cascade = CascadeType.XXX ,orphanRemoval=true)на стороне отца объекта. Затем обновите отца (папа DAO.update (папа)). (Повторите эти действия для каждого объекта отца). В результате у детей обрывается связь с отцом, а затем они удаляются из системы как сироты.

Георгий Папатеодору
источник
5

Я столкнулся с этой проблемой, когда у нас были отношения один-много.

В файл отображения hibernate hbm для мастера, для объекта с заданным типом расположения, добавлено, cascade="save-update"и он работал нормально.

Без этого hibernate по умолчанию пытается обновить несуществующую запись и вместо этого вставляет.

Шив
источник
4

Это также может произойти , когда вы пытаетесь UPDATEс PRIMARY KEY .

завивать волосы щипцами
источник
3

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

MacDaddy
источник
3

Другой способ получить эту ошибку, если у вас есть нулевой элемент в коллекции.

Брайан Пью
источник
2

это происходит, когда вы пытаетесь удалить тот же объект, а затем снова обновить тот же объект, используйте это после удаления

session.clear ();

Сумит Сингх
источник
2

Это также случилось со мной, потому что у меня был свой идентификатор как Long, и я получал из представления значение 0, и когда я попытался сохранить в базе данных, я получил эту ошибку, затем я исправил ее, установив id в ноль.

Роберто Родригес
источник
1

Я столкнулся с этой проблемой, когда вручную начинал и совершал транзакции внутри метода, помеченного как @Transactional. Я исправил проблему, обнаружив, существует ли активная транзакция.

//Detect underlying transaction
if (session.getTransaction() != null && session.getTransaction().isActive()) {
    myTransaction = session.getTransaction();
    preExistingTransaction = true;
} else {
    myTransaction = session.beginTransaction();
}

Затем я позволил Spring обработать транзакцию.

private void finishTransaction() {
    if (!preExistingTransaction) {
        try {
            tx.commit();
        } catch (HibernateException he) {
            if (tx != null) {
                tx.rollback();
            }
            log.error(he);
        } finally {
            if (newSessionOpened) {
                SessionFactoryUtils.closeSession(session);
                newSessionOpened = false;
                maxResults = 0;
            }
        }
    }
}
Gibado
источник
1

Это происходит, когда вы объявили управляемый компонент JSF как

@RequestScoped;

когда вы должны объявить как

@SessionScoped;

С уважением;

Джон Лопес
источник
1

Я получил эту ошибку при попытке обновить объект с идентификатором, который не существует в базе данных. Причиной моей ошибки было то, что я вручную назначил свойство с именем 'id' для JSON-представления объекта на стороне клиента, а затем при десериализации объекта на стороне сервера это свойство 'id' перезаписывало бы переменную экземпляра ( также называемый «id»), который должен был генерировать Hibernate. Поэтому будьте осторожны с именами коллизий, если вы используете Hibernate для генерации идентификаторов.

Soggiorno
источник
1

Я также столкнулся с той же проблемой. В моем случае я обновлял объект, который даже не существовал, используя hibernateTemplate.

На самом деле в моем приложении я получал объект БД для обновления. И, обновляя его значения, я также по ошибке обновил его идентификатор, продолжил его обновление и столкнулся с упомянутой ошибкой.

Я использую hibernateTemplateдля операций CRUD.

Кулдип Верма
источник
1

После прочтения всех ответов не нашел никого, кто мог бы поговорить об обратном атрибуте hibernate.

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

Предположим, у нас есть две таблицы:

principal_table , middle_table

с отношением одного ко многим . Классы отображения спящего режима - Главный и Средний соответственно.

Таким образом, у класса Principal есть набор объектов Middle . Файл отображения xml должен выглядеть следующим образом:

<hibernate-mapping>
    <class name="path.to.class.Principal" table="principal_table" ...>
    ...
    <set name="middleObjects" table="middle_table" inverse="true" fetch="select">
        <key>
            <column name="PRINCIPAL_ID" not-null="true" />
        </key>
        <one-to-many class="path.to.class.Middel" />
    </set>
    ...

Поскольку для параметра инверсии задано значение «истина», это означает, что «средний» класс является владельцем отношения, поэтому основной класс НЕ ОБНОВЛЯЕТ отношение.

Таким образом, процедура обновления может быть реализована так:

session.beginTransaction();

Principal principal = new Principal();
principal.setSomething("1");
principal.setSomethingElse("2");


Middle middleObject = new Middle();
middleObject.setSomething("1");

middleObject.setPrincipal(principal);
principal.getMiddleObjects().add(middleObject);

session.saveOrUpdate(principal);
session.saveOrUpdate(middleObject); // NOTICE: you will need to save it manually

session.getTransaction().commit();

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

Луис Тейджон
источник
1

В нашем случае мы наконец выяснили причину возникновения StaleStateException.

Фактически мы удаляли строку дважды в одном сеансе гибернации. Ранее мы использовали ojdbc6 lib, и в этой версии это было нормально.

Но когда мы обновились до odjc7 или ojdbc8, удаление записей дважды было исключением. В нашем коде была ошибка, из-за которой мы дважды удаляли, но в ojdbc6 это было неочевидно.

Мы смогли воспроизвести этот фрагмент кода:

Detail detail = getDetail(Long.valueOf(1396451));
session.delete(detail);
session.flush();
session.delete(detail);
session.flush();

При первом сбросе гибернация идет и вносит изменения в базу данных. Во время 2-го сброса hibernate сравнивает объект сеанса с фактической записью таблицы, но не может найти один, следовательно, исключение.

Сандип Хантвал
источник
1

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

Я использовал session.evict (); чтобы сначала удалить кэш, хранящийся в спящем режиме, или, если вы не хотите рисковать потерей данных, лучше создать другой объект для хранения временных данных.

     try
    {
        if(!session.isOpen())
        {
            session=EmployeyDao.getSessionFactory().openSession();
        }
            tx=session.beginTransaction();

        session.evict(e);
        session.saveOrUpdate(e);
        tx.commit();;
        EmployeyDao.shutDown(session);
    }
    catch(HibernateException exc)
    {
        exc.printStackTrace();
        tx.rollback();
    }
Амит Мишра
источник
1

Hibernate 5.4.1 и выпуск HHH-12878

До Hibernate 5.4.1 исключения сбоя оптимистической блокировки (например, StaleStateExceptionили OptimisticLockException) не включали оператор сбоя.

Проблема HHH-12878 была создана для улучшения Hibernate, чтобы при создании исключения оптимистической блокировки PreparedStatementтакже регистрировалась реализация JDBC :

if ( expectedRowCount > rowCount ) {
    throw new StaleStateException(
            "Batch update returned unexpected row count from update ["
                    + batchPosition + "]; actual row count: " + rowCount
                    + "; expected: " + expectedRowCount + "; statement executed: "
                    + statement
    );
}

Время тестирования

Я создал BatchingOptimisticLockingTestв своем высокопроизводительном хранилище Java Persistence GitHub, чтобы продемонстрировать, как работает новое поведение.

Во-первых, мы определим Postсущность, которая определяет @Versionсвойство, следовательно, задействуя механизм неявной оптимистической блокировки :

@Entity(name = "Post")
@Table(name = "post")
public class Post {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Long id;

    private String title;

    @Version
    private short version;

    public Long getId() {
        return id;
    }

    public Post setId(Long id) {
        this.id = id;
        return this;
    }

    public String getTitle() {
        return title;
    }

    public Post setTitle(String title) {
        this.title = title;
        return this;
    }

    public short getVersion() {
        return version;
    }
}

Мы включим пакетирование JDBC, используя следующие 3 свойства конфигурации:

properties.put("hibernate.jdbc.batch_size", "5");
properties.put("hibernate.order_inserts", "true");
properties.put("hibernate.order_updates", "true");

Мы собираемся создать 3 Postобъекта:

doInJPA(entityManager -> {
    for (int i = 1; i <= 3; i++) {
        entityManager.persist(
            new Post()
                .setTitle(String.format("Post no. %d", i))
        );
    }
});

И Hibernate выполнит пакетную вставку JDBC:

SELECT nextval ('hibernate_sequence')
SELECT nextval ('hibernate_sequence')
SELECT nextval ('hibernate_sequence')

Query: [
    INSERT INTO post (title, version, id) 
    VALUES (?, ?, ?)
], 
Params:[
    (Post no. 1, 0, 1), 
    (Post no. 2, 0, 2), 
    (Post no. 3, 0, 3)
]

Итак, мы знаем, что пакетная обработка JDBC работает просто отлично.

Теперь давайте повторим проблему с оптимистической блокировкой:

doInJPA(entityManager -> {
    List<Post> posts = entityManager.createQuery("""
        select p 
        from Post p
        """, Post.class)
    .getResultList();

    posts.forEach(
        post -> post.setTitle(
            post.getTitle() + " - 2nd edition"
        )
    );

    executeSync(
        () -> doInJPA(_entityManager -> {
            Post post = _entityManager.createQuery("""
                select p 
                from Post p
                order by p.id
                """, Post.class)
            .setMaxResults(1)
            .getSingleResult();

            post.setTitle(post.getTitle() + " - corrected");
        })
    );
});

Первая транзакция выбирает все Postобъекты и изменяет titleсвойства.

Однако, прежде чем первый EntityManagerбудет сброшен, мы собираемся выполнить второй переход, используя executeSyncметод.

Вторая транзакция изменяет первую Post, поэтому она versionбудет увеличиваться:

Query:[
    UPDATE 
        post 
    SET 
        title = ?, 
        version = ? 
    WHERE 
        id = ? AND 
        version = ?
], 
Params:[
    ('Post no. 1 - corrected', 1, 1, 0)
]

Теперь, когда первая транзакция попытается EntityManagerсбросить, мы получим OptimisticLockException:

Query:[
    UPDATE 
        post 
    SET 
        title = ?, 
        version = ? 
    WHERE 
        id = ? AND 
        version = ?
], 
Params:[
    ('Post no. 1 - 2nd edition', 1, 1, 0), 
    ('Post no. 2 - 2nd edition', 1, 2, 0), 
    ('Post no. 3 - 2nd edition', 1, 3, 0)
]

o.h.e.j.b.i.AbstractBatchImpl - HHH000010: On release of batch it still contained JDBC statements

o.h.e.j.b.i.BatchingBatch - HHH000315: Exception executing batch [
    org.hibernate.StaleStateException: 
    Batch update returned unexpected row count from update [0]; 
    actual row count: 0; 
    expected: 1; 
    statement executed: 
        PgPreparedStatement [
            update post set title='Post no. 3 - 2nd edition', version=1 where id=3 and version=0
        ]
], 
SQL: update post set title=?, version=? where id=? and version=?

Итак, вам нужно перейти на Hibernate 5.4.1 или новее, чтобы воспользоваться этим улучшением.

Влад Михалча
источник
0

Это произошло, если вы изменили что-то в наборе данных, используя собственный SQL-запрос, но постоянный объект для того же набора данных присутствует в кеше сеанса. Используйте session.evict (yourObject);

абхи
источник
0

Hibernate кэширует объекты из сеанса. Если объект доступен и изменен более чем org.hibernate.StaleStateExceptionодним пользователем, он может быть брошен. Это может быть решено с помощью метода слияния / обновления объекта перед сохранением или использованием блокировки. Дополнительная информация: http://java-fp.blogspot.lt/2011/09/orghibernatestalestateexception-batch.html

Как только
источник
0

Один из случаев

SessionFactory sf=new Configuration().configure().buildSessionFactory();
Session session=sf.openSession();

UserDetails user=new UserDetails();

session.beginTransaction();
user.setUserName("update user agian");
user.setUserId(12);
session.saveOrUpdate(user);
session.getTransaction().commit();
System.out.println("user::"+user.getUserName());

sf.close();
vootla561
источник
0

Я столкнулся с этим исключением, и Hibernate работал хорошо. Я попытался вручную вставить одну запись с помощью pgAdmin, здесь проблема стала ясной. Запрос SQL вставки возвращает 0 вставки. и есть триггерная функция, которая вызывает эту проблему, потому что она возвращает ноль. поэтому я должен только установить его, чтобы вернуть новый. и наконец я решил проблему.

надеюсь, что это поможет любому телу.

kamel2005
источник
0

Я получил эту ошибку, потому что я по ошибке сопоставил IDстолбец, используяId(x => x.Id, "id").GeneratedBy.**Assigned**();

Проблема решена с помощью Id(x => x.Id, "id").GeneratedBy.**Identity**();

roylac
источник
0

Это происходит со мной, потому что я пропускаю объявление идентификатора в классе бина.

Ганеш Гири
источник
0

В моем случае была проблема с базой данных, так как один из сохраненных процессов потреблял весь процессор, вызывая большое время отклика БД. Как только это было убито, проблема была решена.

Amit
источник