为什么在读取数据库 hsqldb 中的 blob 时抛出 java.lang.IndexOutOfBoundsException
Why throwing java.lang.IndexOutOfBoundsException when reading blob in the database hsqldb
你好。我正在使用以下代码在服务器端将 blob 写入数据库。
@Override
public void write(TypeHandlerContext context, ResultSet resultSet, Object value) {
int column = context.getColumn();
LargeObject lo = (LargeObject)value;
if(lo == null) {
try {
resultSet.updateNull(column);
} catch(SQLException e) {
throw new RuntimeException(e);
}
} else {
InputStream is = lo.getInputStream();
try {
if(is == null) {
Reader r = lo.getReader();
if(r == null) {
resultSet.updateNull(column);
return;//empty Large object
}
is = new ReaderInputStream(r, "UTF-8");
}
resultSet.updateBlob(column, is, lo.getLength());
} catch(Exception e) {
Throwables.throwAsUndeclarable(e);
} finally {
Tools.closeSilent(is);
}
}
}
读取 blob 使用以下代码:
@Override
public LargeObject read(TypeHandlerContext context, ResultSet resultSet) {
try {
Blob blob = resultSet.getBlob(context.getColumn());
if(blob == null) {
return null;
}
final long len = blob.length();
final byte[] bytes = readBytes((int)len, blob);
return new ByteArrayLargeObject(bytes, true, false);
} catch(Exception e) {
Throwables.throwAsUndeclarable(e);
return null;
}
}
private byte[] readBytes(int len, Blob blob) throws Exception {
try {
return blob.getBytes(1l, len);
} catch(SQLFeatureNotSupportedException e) {
InputStream is = blob.getBinaryStream();
try {
return IOUtils.toByteArray(is, len);
} finally {
Tools.closeSilent(is);
}
}
}
Blob 包含下一个测试文本:
and(
gt(
field("sinSystems.childsCount"),
param(0, "integer")
),
security.checkAccessForTarget("sinSystems.target", "sinSystems.targetType")
)
我已经在 oracle 和 postresql 上测试成功,但在 hsqldb 上测试失败,异常:
Caused by: java.lang.IndexOutOfBoundsException: Index out of bounds: 0 >= 0
at org.hsqldb.lib.HsqlArrayList.get(Unknown Source)
at org.hsqldb.persist.LobStoreMem.getBlockBytes(Unknown Source)
at org.hsqldb.persist.LobManager.getBytesNormal(Unknown Source)
at org.hsqldb.persist.LobManager.getBytes(Unknown Source)
at org.hsqldb.Session.performLOBOperation(Unknown Source)
at org.hsqldb.Session.execute(Unknown Source)
at org.hsqldb.types.BlobDataID.getBytes(Unknown Source)
at org.hsqldb.jdbc.JDBCBlobClient.getBytes(Unknown Source)
at ru.kih.sin.db.types.LargeObjectHandler.readBytes(LargeObjectHandler.java:100)
at ru.kih.sin.db.types.LargeObjectHandler.read(LargeObjectHandler.java:44)
at ru.kih.sin.db.types.LargeObjectHandler.read(LargeObjectHandler.java:27)
at ru.kih.sql.types.NullValueWrapper.read(NullValueWrapper.java:24)
at ru.kih.sql.types.TypeHandlerWrapper.read(TypeHandlerWrapper.java:74)
at ru.kih.sql.types.TypeConverter.read(TypeConverter.java:48)
at ru.kih.sin.model.impl.ObjectReadFunction.apply(ObjectReadFunction.java:119)
at ru.kih.sin.model.impl.ObjectHandler.handle(ObjectHandler.java:41)
at ru.kih.sin.model.impl.ObjectHandler.handle(ObjectHandler.java:16)
at ru.kih.sql.query.handlers.SimpleSelect.handle(SimpleSelect.java:63)
at ru.kih.sql.query.QueryHelper$UnsafeFunctionImpl.apply(QueryHelper.java:39)
at ru.kih.sql.query.QueryHelper$UnsafeFunctionImpl.apply(QueryHelper.java:25)
at ru.kih.sql.query.QueryContext.runIn(QueryContext.java:479)
at ru.kih.sql.query.QueryContext.run(QueryContext.java:228)
at ru.kih.sql.query.QueryContext.run(QueryContext.java:212)
at ru.kih.sql.query.QueryContext.call(QueryContext.java:242)
at ru.kih.sql.query.QueryHelper.query(QueryHelper.java:57)
at ru.kih.sin.model.impl.SelectLobFunction.apply(SelectLobFunction.java:62)
at ru.kih.sin.model.impl.SelectLobFunction.apply(SelectLobFunction.java:24)
at ru.kih.sql.query.QueryContext.runIn(QueryContext.java:479)
at ru.kih.sql.query.QueryContext.run(QueryContext.java:228)
at ru.kih.sql.query.QueryContext.run(QueryContext.java:212)
at ru.kih.sql.query.QueryContext.call(QueryContext.java:242)
at ru.kih.sin.model.impl.ModelImpl.lambda$loadLob(ModelImpl.java:280)
at ru.kih.sin.model.impl.ModelImpl$$Lambda/26663026.call(Unknown Source)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at ru.kih.sin.model.impl.ModelImpl.loadLob(ModelImpl.java:285)
... 48 more
调试器可以看到 blob.getLength() 大于 0。
使用驱动程序 hsqldb-2.3.1 连接数据库
告诉我有什么问题?
P.S. 对不起我的英语))
写入blob的代码不完整。您必须在 resultSet.updateBlob(...)
.
之后调用 resultSet.updateRow()
最好使用最新版本的 HSQLDB,目前为 2.3.2 和 2.3.3(候选发布版)。
答案已关闭。方法 public void write(TypeHandlerContext context, ResultSet resultSet, Object value)
的行 Tools.closeSilent(is);
中的问题。它在调用 resultSet.updateRow()
.
之前关闭 InputStream
你好。我正在使用以下代码在服务器端将 blob 写入数据库。
@Override
public void write(TypeHandlerContext context, ResultSet resultSet, Object value) {
int column = context.getColumn();
LargeObject lo = (LargeObject)value;
if(lo == null) {
try {
resultSet.updateNull(column);
} catch(SQLException e) {
throw new RuntimeException(e);
}
} else {
InputStream is = lo.getInputStream();
try {
if(is == null) {
Reader r = lo.getReader();
if(r == null) {
resultSet.updateNull(column);
return;//empty Large object
}
is = new ReaderInputStream(r, "UTF-8");
}
resultSet.updateBlob(column, is, lo.getLength());
} catch(Exception e) {
Throwables.throwAsUndeclarable(e);
} finally {
Tools.closeSilent(is);
}
}
}
读取 blob 使用以下代码:
@Override
public LargeObject read(TypeHandlerContext context, ResultSet resultSet) {
try {
Blob blob = resultSet.getBlob(context.getColumn());
if(blob == null) {
return null;
}
final long len = blob.length();
final byte[] bytes = readBytes((int)len, blob);
return new ByteArrayLargeObject(bytes, true, false);
} catch(Exception e) {
Throwables.throwAsUndeclarable(e);
return null;
}
}
private byte[] readBytes(int len, Blob blob) throws Exception {
try {
return blob.getBytes(1l, len);
} catch(SQLFeatureNotSupportedException e) {
InputStream is = blob.getBinaryStream();
try {
return IOUtils.toByteArray(is, len);
} finally {
Tools.closeSilent(is);
}
}
}
Blob 包含下一个测试文本:
and( gt( field("sinSystems.childsCount"), param(0, "integer") ), security.checkAccessForTarget("sinSystems.target", "sinSystems.targetType") )
我已经在 oracle 和 postresql 上测试成功,但在 hsqldb 上测试失败,异常:
Caused by: java.lang.IndexOutOfBoundsException: Index out of bounds: 0 >= 0
at org.hsqldb.lib.HsqlArrayList.get(Unknown Source)
at org.hsqldb.persist.LobStoreMem.getBlockBytes(Unknown Source)
at org.hsqldb.persist.LobManager.getBytesNormal(Unknown Source)
at org.hsqldb.persist.LobManager.getBytes(Unknown Source)
at org.hsqldb.Session.performLOBOperation(Unknown Source)
at org.hsqldb.Session.execute(Unknown Source)
at org.hsqldb.types.BlobDataID.getBytes(Unknown Source)
at org.hsqldb.jdbc.JDBCBlobClient.getBytes(Unknown Source)
at ru.kih.sin.db.types.LargeObjectHandler.readBytes(LargeObjectHandler.java:100)
at ru.kih.sin.db.types.LargeObjectHandler.read(LargeObjectHandler.java:44)
at ru.kih.sin.db.types.LargeObjectHandler.read(LargeObjectHandler.java:27)
at ru.kih.sql.types.NullValueWrapper.read(NullValueWrapper.java:24)
at ru.kih.sql.types.TypeHandlerWrapper.read(TypeHandlerWrapper.java:74)
at ru.kih.sql.types.TypeConverter.read(TypeConverter.java:48)
at ru.kih.sin.model.impl.ObjectReadFunction.apply(ObjectReadFunction.java:119)
at ru.kih.sin.model.impl.ObjectHandler.handle(ObjectHandler.java:41)
at ru.kih.sin.model.impl.ObjectHandler.handle(ObjectHandler.java:16)
at ru.kih.sql.query.handlers.SimpleSelect.handle(SimpleSelect.java:63)
at ru.kih.sql.query.QueryHelper$UnsafeFunctionImpl.apply(QueryHelper.java:39)
at ru.kih.sql.query.QueryHelper$UnsafeFunctionImpl.apply(QueryHelper.java:25)
at ru.kih.sql.query.QueryContext.runIn(QueryContext.java:479)
at ru.kih.sql.query.QueryContext.run(QueryContext.java:228)
at ru.kih.sql.query.QueryContext.run(QueryContext.java:212)
at ru.kih.sql.query.QueryContext.call(QueryContext.java:242)
at ru.kih.sql.query.QueryHelper.query(QueryHelper.java:57)
at ru.kih.sin.model.impl.SelectLobFunction.apply(SelectLobFunction.java:62)
at ru.kih.sin.model.impl.SelectLobFunction.apply(SelectLobFunction.java:24)
at ru.kih.sql.query.QueryContext.runIn(QueryContext.java:479)
at ru.kih.sql.query.QueryContext.run(QueryContext.java:228)
at ru.kih.sql.query.QueryContext.run(QueryContext.java:212)
at ru.kih.sql.query.QueryContext.call(QueryContext.java:242)
at ru.kih.sin.model.impl.ModelImpl.lambda$loadLob(ModelImpl.java:280)
at ru.kih.sin.model.impl.ModelImpl$$Lambda/26663026.call(Unknown Source)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at ru.kih.sin.model.impl.ModelImpl.loadLob(ModelImpl.java:285)
... 48 more
调试器可以看到 blob.getLength() 大于 0。
使用驱动程序 hsqldb-2.3.1 连接数据库
告诉我有什么问题?
P.S. 对不起我的英语))
写入blob的代码不完整。您必须在 resultSet.updateBlob(...)
.
resultSet.updateRow()
最好使用最新版本的 HSQLDB,目前为 2.3.2 和 2.3.3(候选发布版)。
答案已关闭。方法 public void write(TypeHandlerContext context, ResultSet resultSet, Object value)
的行 Tools.closeSilent(is);
中的问题。它在调用 resultSet.updateRow()
.
InputStream