Метод удаления в Hibernate, предоставляющий StaleStateException - PullRequest
0 голосов
/ 18 января 2011

Я пытаюсь удалить объект, используя метод удаления Hibernate, но получаю исключение StaleStateException. Моё требование - удалить объект на основе уникального ключа, поэтому для этого я делаю что-то вроде.

String queryString="from Destination destination "+
                                                   "where destination.destinationID = :destinationid";
    tx.begin();
                Query query= session.createQuery(queryString).setParameter("destinationid", destinationId, Hibernate.STRING);
               @SuppressWarnings("unchecked")
               List<Destination> list=query.list();
               Destination ds=list.get(0);
                 if(!list.isEmpty())
                  session.evict(ds);
                  session.delete(ds);

                  tx.commit();

, так как язнаю, что в списке будет только один элемент, если он не пустой, поэтому только выборка первого элемента из списка (не уверен, что это хороший подход)

, но когда я запускаю этот метод, я вижуследующий sql log в моей консоли

Hibernate: 
    /* delete collection AirTransport.timeTable */ delete 
        from
            tr.TRANSPORTTIME 
        where
            TRANSPORTID=?
Hibernate: 
    /* delete collection AirTransport.timeTable */ delete 
        from
            tr.TRANSPORTTIME 
        where
            TRANSPORTID=?
Hibernate: 
    /* delete collection AirTransport.timeTable */ delete 
        from
            tr.TRANSPORTTIME 
        where
            TRANSPORTID=?
Hibernate: 
    /* delete collection RoadTransport.timeTable */ delete 
        from
            tr.TRANSPORTTIME 
        where
            TRANSPORTID=?
Hibernate: 
    /* delete collection TrainTransport.timeTable */ delete 
        from
            tr.TRANSPORTTIME 
        where
            TRANSPORTID=?
Hibernate: 
    /* delete AirTransport */ delete 
        from
            tr.TRANSPORT 
        where
            UUID=?
Hibernate: 
    /* delete AirTransport */ delete 
        from
            tr.TRANSPORT 
        where
            UUID=?
Hibernate: 
    /* delete AirTransport */ delete 
        from
            tr.TRANSPORT 
        where
            UUID=?
Hibernate: 
    /* delete RoadTransport */ delete 
        from
            tr.TRANSPORT 
        where
            UUID=?

и чем его бросание

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:61)
 at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:46)

одна вещь, которая вызывает у меня подозрение, состоит в том, что в моей таблице транспорта у меня есть три записи только одна для AirTransport одна дляПоезд и последний для Road и в таблице TransPortTime у меня есть три записи по одной для каждого типа транспорта и

Я использую TransportTime в качестве составного элемента для всех трех классов транспорта

<set name="timeTable" table="TRANSPORTTIME" lazy="true">
                        <key column="TRANSPORTID"/>
                        <composite-element
                                class="TransportTime">

                                <property name="deperatureTime" type="java.util.Date">
                                        <column name="DEPERATURETIME" />
                                </property>
                                <property name="arrivalTime" type="java.util.Date">
                                        <column name="ARRIVALTIME" />
                                </property>
                                <other properties>
                        </composite-element>

                </set>

Я до сих пор не могу понять, что происходит, поэтому спрашиваю в сообществе


ПростоЧтобы добавить дополнительную информацию: у меня есть приведенное ниже отображение в моем классе назначения для трех соответствующих классов транспорта

<set name="airTransport" table="AIRTRANSPORT" inverse="true" lazy="true" cascade="save-update, delete">
        <key>
            <column name="DESTINATIONID" />
        </key>
        <one-to-many class="AirTransport" />
    </set>
    <set name="roadTransport" table="ROADTRANSPORT" inverse="true" lazy="true" cascade="save-update, delete">
        <key>
            <column name="DESTINATIONID" />
        </key>
        <one-to-many class="RoadTransport" />
    </set>
    <set name="trainTransport" table="TRAINTRANSPORT" inverse="true" lazy="true" cascade="save-update, delete">
        <key>
            <column name="DESTINATIONID" />
        </key>
        <one-to-many class="TrainTransport" />
    </set>

и в моем RoadTransport / Train / Air Transport есть следующее отображение

<class name="AirTransport" table="TRANSPORT">
        <id name="uuid" type="java.lang.String">
            <column name="UUID" />
            <generator class="uuid"/>
        </id>
        <many-to-one name="destination" class="Destination" fetch="join">
            <column name="DESTINATIONID" />
        </many-to-one>
       <property mappings>
        <set name="timeTable" table="TRANSPORTTIME" lazy="true">
            <key column="TRANSPORTID"/>
            <composite-element
                class="TransportTime">
                <property mappings>
                </composite-element>

        </set>
    </class>

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

Так что это означает, что я делаю принципиально неверную задачу при сопоставлении класса TimeTable как компонента внутриКлассы транспорта (класс воздушного / железнодорожного / автомобильного транспорта)

. Любое предложение по этому вопросу будет очень полезным

.

Ответы [ 2 ]

3 голосов
/ 18 января 2011

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

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

http://www.dil.univ -mrs.fr / ~ massat / docs / hibernate-3.1 / api / org / hibernate / StaleStateException.html

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

Также у класса Query должен быть какой-то методс именем uniqueResult(), который вернет один результат объекта, если вы уверены, что он будет возвращать один результат каждый раз, когда вы его выполняете.Это сэкономит вам некоторый код при попытке получить 0-й индекс части списка.

1 голос
/ 18 января 2011

Ваш код неверен (как минимум) двумя способами:

  • Вы должны проверить isEmpty() до получения 0-го предмета. В противном случае вы рискуете исключением
  • Вы не должны выселять перед удалением. Избавьтесь от линии evict()

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

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