org.hibernate.StaleStateException: пакетное обновление вернуло неожиданное количество строк из-за обновления [0];фактическое количество строк: 0;ожидается: 1 - PullRequest
5 голосов
/ 23 февраля 2011

Иногда при сохранении объекта obj одно из его полей слишком велико, чтобы поместиться в поле db, что приводит к исключению усечения данных.В следующем коде я пытаюсь перехватить DataException и просто очистить поле и выполнить повторное сохранение.Однако я получаю исключение при спасении.Почему возникает исключение пакетного обновления и как его обойти?


 public static void save(Object obj) throws Exception{
        try{
            beginTransaction();
            getSession().save(obj);
            commitTransaction();

        }catch(Exception e){
            e.printStackTrace();
            rollbackTransaction();
            throw e;
        }finally{
            closeSession(); //not needed, session obtained from sf.getCurrentSession() will auto close
        }
    }   
 public static void saveXXX(XXX rec){

        try {
            save(rec);
        } catch (org.hibernate.exception.DataException e) {
            e.printStackTrace();

            saveXXX(rec, e); //causes an exception      
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
    private static void saveXXX(WhoisRecord rec, DataException e) {
        rec.setField(""); //empty out the problem field
        saveXXX(rec);

Исключение:

org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
    at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:85)
    at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:70)
    at org.hibernate.jdbc.BatchingBatcher.checkRowCounts(BatchingBatcher.java:90)
    at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
    at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:114)
    at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:109)
    at org.hibernate.jdbc.AbstractBatcher.prepareBatchStatement(AbstractBatcher.java:244)
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2382)
    at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2335)
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2635)
    at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:115)
    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:168)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027)
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:365)
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:137)
.
.
.

Ответы [ 5 ]

3 голосов
/ 16 сентября 2011

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

Похоже, что вы пытаетесь сохранить запись, и Hibernate выдает это исключение усечения данных, то есть сохраняет что-то, но не все, что вы хотели. Таким образом, вы ловите это исключение и пытаетесь откатить транзакцию. Но это не всегда гарантирует успех (из того, что я вижу в Hibernate save () и откат транзакции ), поэтому сохраненные данные все еще могут быть там. Давайте предположим, что это так. Затем вы изменяете свою запись и пытаетесь сохранить ее снова.

Но так как данные все еще там, вызов save ничего не сделает, так как в этом случае это должно быть обновление. Поэтому, когда вы пытаетесь зафиксировать эту транзакцию, Hibernate знает, что вы хотите сохранить 1 запись, но он успешно сохраняет 0, что приводит к ошибке.

Попробуйте изменить getSession (). Save (obj); на getSession (). SaveOrUpdate (obj); . Это должно сохранить запись, когда она не существует, и обновить ее (чтобы не было слишком большого поля), когда она существует.

3 голосов
/ 13 марта 2012

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

Столбец ключа был определен как автоинкремент(в MySQL), и с этим отображением

<id name="tableId" type="long" access="field">
   <column name="tableId" />
   <generator class="assigned" />
</id>

я получил исключение StaleStateException, но когда я исправил запись в

<id name="tableId" type="long" access="field">
   <column name="tableId" />
   <generator class="native" />
</id>

, тогда она работала без проблем.

2 голосов
/ 02 апреля 2011

У меня недостаточно подсказок, чтобы сказать вам точно.Я могу просто сказать, что у меня была та же проблема, и я решил вызвать merge () вместо save ().Вы всегда должны использовать merge () в случае, если отдельные объекты.

1 голос
/ 22 мая 2014

Что я испытал, так это то, что это исключение возникает при обновлении объекта с идентификатором, которого нет в таблице.если вы читаете сообщение об исключении, оно говорит: «Пакетное обновление вернуло неожиданное количество строк из обновления [0]; фактическое количество строк: 0; ожидается: 1», что означает, что не удалось найти запись с заданным вами идентификатором.

Комучтобы избежать этого, я всегда читаю запись с тем же идентификатором, если я нашел запись назад, тогда я вызываю update, в противном случае выдается «исключительная запись не найдена».

1 голос
/ 20 апреля 2014

Это приходит из вашего файла сопоставления. Класс собственного генератора отображается на последовательность в Oracle. Либо создайте последовательность (не знаю, какое базовое имя она использовала, но я предполагаю, что она есть в документах гибернации), либо переключитесь на другой генератор.

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

http://forum.spring.io/forum/spring-projects/data/19856-not-saving-in-an-oracle-data-base

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