PostgreSQL JDBC Null字符串作为bytea

lai*_*ook 12 string postgresql null hibernate jdbc

如果在代码片段后entity.getHistory()为null:

(getEntityManager()返回弹簧注入的EntityManager,数据库字段历史类型为:text或varchar2(2000)

Query query = getEntityManager().createNativeQuery("insert into table_name(..., history, ....) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
[...]
.setParameter(6, entity.getHistory())
[...]

query.executeUpdate();
Run Code Online (Sandbox Code Playgroud)

给出奇怪的例外:

17/11/11 06:26:09:009 [pool-2-thread-1]  WARN util.JDBCExceptionReporter:100 - SQL Error: 0, SQLState: 42804
17/11/11 06:26:09:009 [pool-2-thread-1] ERROR util.JDBCExceptionReporter:101 - ERROR: **column "history" is of type text but expression is of type bytea**
Run Code Online (Sandbox Code Playgroud)

提示:您需要重写或转换表达式.

仅在此配置中出现问题:
操作系统:CentOS版本5.6(最终版)
Java:1.6.0_26
DB:PostgreSQL 8.1
JDBC驱动程序:postgresql-9.1-901.jdbc4
应用程序服务器:apache-tomcat-6.0.28

在其他一些配置或历史记录为空字符串时,一切正常.从pgAdmin执行的相同语句工作正常.

我想问题是在PostgreSQL JDBC驱动程序中,是否有一些明智的理由将空字符串视为bytea值?Postgres 8和9之间可能有一些奇怪的变化?

ara*_*nid 5

由于您使用setParameter(int,Object)空值进行调用,因此猜测实体管理器不知道使用哪种持久性类型来绑定参数。Istr Hibernate 偏爱使用 SerializableType,这相当于一个字节。

您可以使用带有 Parameter 对象的 setParameter 方法,以便指定类型吗?我没有真正使用过JPA,所以不能给出详细的指针。

(恕我直言,这是您滥用 EntityManager 的本机 sql 查询接口进行插入的唯一甜点,而不是实际映射实体,或者只是直接插入 JDBC)


Dan*_*ein 5

有一个简单的修复:当你构建查询字符串时,如果参数为null - 使用"null"而不是"?".

正如@araqnid所说,Hibernate错误地将null值转换为bytea类型,因为它不知道更好.


Mat*_*att 2

如果您愿意使用PreparedStatement类而不是Query:

if (entity.getHistory() == null)
    stmt.setNull(6, Types.VARCHAR);
else
    stmt.setString(6, entity.getHistory());
Run Code Online (Sandbox Code Playgroud)

(在查询字符串中使用也可能?::text有效,但我自己从未这样做过。)