NutzCN Logo
问答 postgresql 获取 blob得到null
发布于 2439天前 作者 tiger 3371 次浏览 复制 上一个帖子 下一个帖子
标签:

postgresql 10,nutz 1.r.65,1.r.62

@Table("t_use_blob_clob")
public class UseBlobClob {

    @Id
    private long id;
    
    @Name
    private String name;
    
    private Blob x;
    
    private Clob y;

字段y类型Clob,插入/获取都可以。字段x为Blob,插入可以,获取时为null。

	        use = null;
	        use = dao.fetch(UseBlobClob.class);
	        System.err.println("x: "+use.getX());

x: null

14 回复

这个有点神奇,有可能是bug

调试了一下,在BlobValueAdaptor.java中get函数的rs.getBlob(colName)时有异常扔出。
也就是 PgResultSet.getBlob。
SQLState "22003" (id=2028) : 22003 numeric_value_out_of_range
detailMessage "不良的类型值 long : \x3c70726f6a65637420786d6c6e733d22687474703a2f2f6d6176656e2e6170616368652e6f72672f504f4d2f342e302e302220786d6c6e733a7873693d22687474703a2f2f7777772....."

    public Object get(ResultSet rs, String colName) throws SQLException {
        Blob blob = rs.getBlob(colName);
        if (blob == null)
            return null;
        File f = this.createTempFile();
        Files.write(f, blob.getBinaryStream());
        return new SimpleBlob(f);
    }

colName的值是对的,rs也是对的(字段都取到了),但就是rs.getBlob(colName)有异常,导致SetValue没有被实际执行。

pgsql的版本太低了吧?

postgresql 是 10.1。

另外,PgResultSet.getBlob在迭代到x字段时,被调用,应该说可以认为字段类型就是blob
但是随后,getBlob会调用PgResultSet.isBinary方法,结果它认为x这个字段是text,不是binary,真是奇怪

10 是 postgresql 最新的大版本,驱动也比较新

        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>42.1.4</version>
        </dependency>

public class PgResultSet implements ResultSet, org.postgresql.PGRefCursorResultSet {

  public Blob getBlob(int i) throws SQLException {
    checkResultSet(i);
    if (wasNullFlag) {
      return null;
    }

    return makeBlob(getLong(i));
  }
  

  public long getLong(int columnIndex) throws SQLException {
...
    if (isBinary(columnIndex)) {
...
      return readLongValue(this_row[col], oid, Long.MIN_VALUE, Long.MAX_VALUE, "long");
    }
...
          return getFastLong(columnIndex);
...
  }

  protected boolean isBinary(int column) {//这里返回 false 了,针对blob字段
    return fields[column - 1].getFormat() == Field.BINARY_FORMAT;
  }


  private long getFastLong(int columnIndex) throws SQLException, NumberFormatException {
  ...
      if (bytes.length > 18) {
        throw FAST_NUMBER_FAILED; // 在这里扔出的异常,但个人认为其实getFastLong不应该在Blob字段被调用
      }
  ...
  }

} // end PgResultSet

换最新驱动

数据库里面的字段类型对吗?

字段类型是对的,已换最新驱动

嗯,周末写点代码试试才行了

我记得有对应的testcase

添加回复
请先登陆
回到顶部