Hibernate бросает SQLException Не удалось сбросить читатель - PullRequest
3 голосов
/ 03 октября 2011
java.sql.SQLException: could not reset reader
        at org.hibernate.lob.ClobImpl.getCharacterStream(ClobImpl.java:100)
        at org.hibernate.type.ClobType.set(ClobType.java:70)
        at org.hibernate.type.ClobType.nullSafeSet(ClobType.java:141)
        at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2025)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2271)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2688)
        at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:79)
        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:167)
        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)

Привет,

Над трассировкой стека.Он работает с небольшим объемом данных, но не работает с большими данными.Я не могу понять, в чем может быть проблема?

С уважением, Преет

Ответы [ 2 ]

3 голосов
/ 29 октября 2012

Мы только что решили подобную проблему, и я хотел бы описать эту проблему здесь на случай, если кто-то столкнется с ней. Обратите внимание, что есть еще один вопрос об этой же проблеме. У нас есть Oracle 10, Hibernate 3, Java 1.4 и исправленный Ojdbc14. Мы создали CLOB, используя «Hibernate.createClob (String)». Программа (пакетное задание) завершилась неудачно на больших строках (~ 700 КБ).

Проблема была в том, что в Hibernate мы сначала вставили объект с CLOB и обновили его (включая CLOB). Второе обновление было частью обновления «многие к одному». Между ними CLOB не менялся, просто Hibernate хотел обновить его дважды. И он получил эту «не удалось сбросить» ошибку читателя. Кажется, он не может использовать один и тот же поток дважды. Мы исправили это, убедившись, что CLOB сохраняется только один раз.

0 голосов
/ 13 марта 2019

У нас возникла эта проблема при переносе системы транзакций, поддерживаемой MySQL, в базу данных H2.(Несколько похоже на эту проблему на устаревших форумах Hibernate.)

Наша история

  1. У нас были модели объектов с полями BLOB-объектов.
  2. В коде мы транзакционно извлекали пакеты этих сущностей, обновляли их статус до «обработки», а затем считывали полезные данные больших двоичных объектов за пределами транзакции (после подтверждения обновления статуса) для фактической обработки.
  3. Изначально отложенная загрузка не работала, поэтому каждая выборка извлекала содержимое поля большого двоичного объекта вместе с сущностью.

При фиксации транзакции Hibernate проверяет грязность каждого поля и отправляет обновления для всех грязныхПоля обратно в БД.

В механизме обнаружения изменений Hibernate к двоичным объектам всегда относились как к грязным (возможно, из-за того, что вы не можете сравнивать два больших объекта неинвазивным способом; например, если один большой объект имеет потоковую поддержку, выпришлось бы фактически использовать поток, чтобы сравнить его содержимое с другим BLOB-объектом).

Проверьте:

  • org.hibernate.type.AbstractStandardBasicType#isDirty(java.lang.Object, java.lang.Object, boolean[], org.hibernate.engine.spi.SharedSessionContractImplementor) и
  • org.hibernate.type.descriptor.java.BlobTypeDescriptor#areEqual

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

Хотя вы можете ожидать, что это все равно вернет true (поскольку мы никогда не касаемся поля blob), обтекание прокси и другие внутренние объекты уровня Hibernate приведут к тому, что конечный объект blob будет вообще другим объектом, что не пройдёт тест ==.

В результате ...

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

Это не проблема для MySQL, поскольку ихBLOB-объекты находятся в памяти (и могут быть прочитаны несколько раз, не вызывая исчерпание потока).Однако H2 предоставляет потоковые двоичные объекты, что означает, что они доступны только для чтения.

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

Наше решение

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

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