如果entity.getHistory()在下面的代码片段中为空:
(getEntityManager()返回spring injected EntityManager,数据库字段历史类型为: text或varchar2(2000) )
Query query = getEntityManager().createNativeQuery("insert into table_name(..., history, ....) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
[...]
.setParameter(6, entity.getHistory())
[...]
query.executeUpdate();
给出了奇怪的异常:
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**
提示:您将需要重写或转换表达式。
仅在此配置中出现问题:
操作系统: CentOS版本5.6 (最终版)
Java: 1.6.0_26
数据库: PostgreSQL 8.1
JDBC驱动程序: postgresql-9.1-901.jdbc4
应用服务器: apache-tomcat-6.0.28
在少数其他配置或历史为空字符串时,一切都工作得很好。从pgAdmin执行的相同语句运行正常。
我猜问题出在PostgreSQL JDBC驱动程序中,有什么合理的理由将空字符串视为byte值吗?也许Postgres 8和9之间有一些奇怪的变化?
发布于 2011-11-23 00:01:45
有一个简单的解决方法:在构建查询字符串时,如果参数将为空--使用" null“而不是"?”。
正如@araqnid所说,Hibernate错误地将null值转换为bytea类型,因为它不知道更好的方法。
发布于 2011-11-21 22:35:35
由于您使用空值调用setParameter(int,Object)
,因此实体管理器大概不知道使用哪种持久性类型来绑定参数。Istr Hibernate倾向于使用SerializableType,这等同于bytea。
您是否可以使用接受参数对象的setParameter方法,以便指定类型?我还没有真正使用过JPA,所以不能给出一个详细的指针。
(我的意思是,这只是您滥用EntityManager的原生sql查询接口执行插入操作的甜点,而不是实际映射实体,或者只是直接使用JDBC)
发布于 2014-05-07 01:46:59
使用Hibernate特定会话API可以解决以下问题:
String sql = "INSERT INTO person (id, name) VALUES (:id, :name)";
Session session = em.unwrap(Session.class);
SQLQuery insert = session.createSQLQuery(sql);
sql.setInteger("id", 123);
sql.setString("name", null);
insert.executeUpdate();
我也提交了HHH-9165来报告这个问题,如果它确实是一个错误的话。
https://stackoverflow.com/questions/8211195
复制相似问题