为什么我会收到org.hibernate.HibernateException:读取二进制值时发生IOException

7

我在日志中发现了这个异常,但我之前从未见过它。我使用的是Hibernate 4.1.7版本。

这是否意味着我的数据库已经损坏,或者这是Hibernate中的一个bug?我在这里找到了有关此错误的参考资料,但该资料是针对更早版本的Hibernate,并且已经在Hibernate 4.0中得到修复。

org.hiorg.hibernate.HibernateException: IOException occurred reading a binary value
    at org.hibernate.type.descriptor.java.DataHelper.extractBytes(DataHelper.java:187)
    at org.hibernate.type.descriptor.java.PrimitiveByteArrayTypeDescriptor.wrap(PrimitiveByteArrayTypeDescriptor.java:124)
    at org.hibernate.type.descriptor.java.PrimitiveByteArrayTypeDescriptor.wrap(PrimitiveByteArrayTypeDescriptor.java:41)
    at org.hibernate.type.descriptor.sql.BlobTypeDescriptor$5.doExtract(BlobTypeDescriptor.java:118)
    at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:65)
    at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:269)
    at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:265)
    at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:238)
    at org.hibernate.type.AbstractStandardBasicType.hydrate(AbstractStandardBasicType.java:357)
    at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2807)
    at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1545)
    at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1477)
    at org.hibernate.loader.Loader.getRow(Loader.java:1377)
    at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:644)
    at org.hibernate.loader.Loader.doQuery(Loader.java:854)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:293)
    at org.hibernate.loader.Loader.doList(Loader.java:2382)
    at org.hibernate.loader.Loader.doList(Loader.java:2368)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2198)
    at org.hibernate.loader.Loader.list(Loader.java:2193)
    at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:122)
    at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1618)
    at org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.java:374)
    at com.jthink.songkong.db.SongCache.loadSongsFromDatabase(SongCache.java:57)
    at com.jthink.songkong.analyse.analyser.SongGroup.getSongs(SongGroup.java:48)
    at com.jthink.songkong.analyse.analyser.DiscogsSongGroupMatcher.call(DiscogsSongGroupMatcher.java:63)
    at com.jthink.songkong.analyse.analyser.DiscogsSongGroupMatcher.call(DiscogsSongGroupMatcher.java:28)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:722)
Caused by: java.io.IOException: org.h2.jdbc.JdbcSQLException: IO Exception: "Missing lob entry: 5587/4" [90028-172]
    at org.h2.message.DbException.convertToIOException(DbException.java:348)
    at org.h2.store.LobStorageBackend$LobInputStream.fillBuffer(LobStorageBackend.java:695)
    at org.h2.store.LobStorageBackend$LobInputStream.readFully(LobStorageBackend.java:668)
    at org.h2.store.LobStorageBackend$LobInputStream.read(LobStorageBackend.java:654)
    at org.hibernate.type.descriptor.java.DataHelper.extractBytes(DataHelper.java:179)
    ... 31 more
Caused by: org.h2.jdbc.JdbcSQLException: IO Exception: "Missing lob entry: 5587/4" [90028-172]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:329)
    at org.h2.message.DbException.get(DbException.java:169)
    at org.h2.message.DbException.get(DbException.java:146)
    at org.h2.store.LobStorageBackend.readBlock(LobStorageBackend.java:203)
    at org.h2.store.LobStorageBackend$LobInputStream.fillBuffer(LobStorageBackend.java:692)
    ... 34 more

1
你正在使用哪个数据库,可能是h2-database吗?请问您能告诉我h2 jar版本号吗? - Gyanendra Dwivedi
3个回答

3

让我们从Hibernate的文档开始:

@Lob表示该属性应该被持久化为Blob或Clob,具体取决于属性类型:java.sql.Clob、Character[]、char[]和java.lang.String将被持久化为Clob。java.sql.Blob、Byte[]、byte[]和可序列化类型将被持久化为Blob。

例如:

@Lob
public String getFullText() {
    return fullText;
}

@Lob 
public byte[] getFullCode() {
    return fullCode;
}

了解这一点,可能意味着该对象不在数据库中。也许它已从表中删除,但在引用表中没有被删除。假设从表 Blobs 中删除了带有 id 5 的 Blob,但在表 users_blobs 中仍然被引用,例如:

| user_id | blob_id|
|    4    |    5   | //This entry blob were delete but is still referenced by that table
|    5    |    2   | 

如果是这种情况,您应该重新定义users_blobs(例如)的约束条件,以便在blob被删除时将其删除或将其置为null
此外,这个链接也可能有用: http://h2-database.66688.n3.nabble.com/IO-Exception-quot-Missing-lob-entry-1-0-quot-90028-171-when-trying-to-read-a-BLOB-longer-than-128-bye-td4026236.html

谢谢,我不再有这个问题了,但看起来很可能是所述情况之一,所以谢谢。 - Paul Taylor

1
这肯定是数据库的问题,而不是Hibernate的问题。你需要查看异常的原因,这是在h2数据库代码内部抛出的异常。
Caused by: org.h2.jdbc.JdbcSQLException: IO Exception: "Missing lob entry: 5587/4" [90028-172]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:329)
    at org.h2.message.DbException.get(DbException.java:169)
    at org.h2.message.DbException.get(DbException.java:146)
    at org.h2.store.LobStorageBackend.readBlock(LobStorageBackend.java:203)
    at org.h2.store.LobStorageBackend$LobInputStream.fillBuffer(LobStorageBackend.java:692)

在互联网上搜索“h2 database Missing lob entry”会显示这是一个

特定的错误信息,像这里的答案https://groups.google.com/forum/#!topic/h2-database/xey-czIhocM表明数据库很可能已经损坏。

如果这种情况发生得更频繁,需要进行更多的研究以了解其原因。但最好在那个

组中进行,那里有数据库开发人员进行活动。


感谢您指出潜在问题可能是h2,并提供链接。 - Paul Taylor

1

看起来你正在尝试加载已被删除的数据寄存器,请尝试同步访问该Hibernate DAO。多线程应用程序应该针对每个线程使用一个连接。


我不明白为什么被采纳的答案比我的更好。问题与Blob类型或注释无关,它也可能发生在其他类型上。:E - Raul Lapeira Herrero

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接