项目中使用了Postgres-XC作为关系型数据库,而应用则是部署在IBM WAS中,在WAS控制台的配置了基于postgresql-9.3-1103.jdbc4.jar的数据源,但发现一个问题,某个读取包含timestamp类型字段的查询在创建连接后前几次执行不会报错,但后续的执行就会报错。
Caused by: org.postgresql.util.PsqlException: Unsupported binary encoding of timestamp. at org.postgresql.jdbc2.TimestampUtils.toTimestampBin(TimestampUtils.java:727) at org.postgresql.jdbc2.AbstractJdbc2ResultSet.getTimestamp(AbstractJdbc2ResultSet.java:517) at org.postgresql.jdbc2.AbstractJdbc2ResultSet.getTimestamp(AbstractJdbc2ResultSet.java:2629) at com.ibm.ws.rsadapter.jdbc.WSJdbcResultSet.getTimestamp(WSJdbcResultSet.java:2672) at org.hibernate.type.descriptor.sql.TimestampTypeDescriptor$2.doExtract(TimestampTypeDescriptor.java:62) at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:64) at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:254) at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:250) at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:230) at org.hibernate.type.AbstractStandardBasicType.hydrate(AbstractStandardBasicType.java:331) at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2283) at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1527) at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1455) at org.hibernate.loader.Loader.getRow(Loader.java:1355) at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:611) at org.hibernate.loader.Loader.doQuery(Loader.java:829) at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274) at org.hibernate.loader.Loader.doList(Loader.java:2542) ... 82 more查看postgresql jdbc源码可以看到报错的那段代码。
/** * Returns the sql Timestamp object matching the given bytes with * {@link Oid#TIMESTAMP} or {@link Oid#TIMESTAMPTZ}. * * @param tz The timezone used when received data is {@link Oid#TIMESTAMP},* ignored if data already contains {@link Oid#TIMESTAMPTZ}. * @param bytes The binary encoded timestamp value. * @param timestamptz True if the binary is in GMT. * @return The parsed timestamp object. * @throws PsqlException If binary format could not be parsed. */ public Timestamp toTimestampBin(TimeZone tz,byte[] bytes,boolean timestamptz) throws PsqlException { if (bytes.length != 8) { throw new PsqlException(GT.tr("Unsupported binary encoding of {0}.","timestamp"),PsqlState.BAD_DATETIME_FORMAT); }可以看到得到的是以二进制编码的时间值,在jdbc代码中将其转化为Java中的Timestamp类型,而报错的原因是二进制编码的时间值存在问题。是WAS的问题?还是hibernate的问题?还是postgresql-jdbc的问题?还是postgres-xc的问题?
查看网络资料,发现postgresql-jdbc有两种传输数据的方式,一种是字符串,一种是二进制。使用二进制传输可以减少网络传输所需的字节数,进而提高效率。同时,在postgresql-jdbc中有相对应的配置,所以,如果二进制传输出错,是否可以尝试一下传统的字符串传输呢?