Hibernate 工具无法从 Postgres 表中获取索引信息

Hibernate Tools failing to get index info from Postgres tables

我正在使用 Hibernate Tools 和 Ant 从 Postgres 数据库生成 POJO。

我的数据库有两个简单的 tables:Person 和 Vehicle。每个 table 有两列:id 和 name

生成Person POJO时,Hibernate在尝试获取索引信息时抛出异常:

[hibernatetool] getIndexInfo(null.public.person)
[hibernatetool] Exception while trying to get indexinfo on public.person=Exception while getting index info for public.person

尽管出现此异常,但成功创建了 Person POJO,然后 Ant build 继续生成 Vehicle POJO,但失败了。我相信这是因为上述异常导致交易保持开放状态。

这是完整的日志:

[hibernatetool] Created database namespace [logicalName=Name{catalog=null, schema=null}, physicalName=Name{catalog=null, schema=null}]
[hibernatetool] Created database namespace [logicalName=Name{catalog=null, schema=null}, physicalName=Name{catalog=null, schema=null}]
[hibernatetool] getTables(null.null.null)
[hibernatetool] Adding table person of type TABLE
[hibernatetool] Normalizing identifier quoting [public]
[hibernatetool] Created database namespace [logicalName=Name{catalog=null, schema=public}, physicalName=Name{catalog=null, schema=public}]
[hibernatetool] Normalizing identifier quoting [person]
[hibernatetool] Adding table vehicle of type TABLE
[hibernatetool] Normalizing identifier quoting [public]
[hibernatetool] Normalizing identifier quoting [vehicle]
[hibernatetool] Finding columns for public.person
[hibernatetool] getColumns(null.public.person.null)
[hibernatetool] getPrimaryKeys(null.public.person)
[hibernatetool] Forcing column [id] to be non-null as it is part of the primary key for table [person]
[hibernatetool] primary key for org.hibernate.mapping.Table(public.person) -> org.hibernate.mapping.PrimaryKey(person[org.hibernate.mapping.Column(id)]) as personpkey
[hibernatetool] getIndexInfo(null.public.person)
[hibernatetool] Exception while trying to get indexinfo on public.person=Exception while getting index info for public.person
[hibernatetool] Finding columns for public.vehicle
[hibernatetool] getColumns(null.public.vehicle.null)
[hibernatetool] An exception occurred while running exporter #2:hbm2java (Generates a set of .java files)
[hibernatetool] To get the full stack trace run ant with -verbose
[hibernatetool] org.hibernate.exception.GenericJDBCException: Error while reading column meta data for public.vehicle
[hibernatetool] org.postgresql.util.PSQLException: ERROR: current transaction is aborted, commands ignored until end of transaction block

BUILD FAILED
build.xml:97: org.hibernate.exception.GenericJDBCException: Error while reading column meta data for public.vehicle
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47)
    at org.hibernate.cfg.reveng.dialect.JDBCMetaDataDialect.getColumns(JDBCMetaDataDialect.java:121)
    ... <many more>
Caused by: org.postgresql.util.PSQLException: ERROR: current transaction is aborted, commands ignored until end of transaction block
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2182)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1911)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:173)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:645)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:481)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:361)
    at org.postgresql.jdbc2.AbstractJdbc2DatabaseMetaData.getColumns(AbstractJdbc2DatabaseMetaData.java:2460)
    at org.postgresql.jdbc4.AbstractJdbc4DatabaseMetaData.getColumns(AbstractJdbc4DatabaseMetaData.java:102)
    at org.hibernate.cfg.reveng.dialect.JDBCMetaDataDialect.getColumns(JDBCMetaDataDialect.java:99)
    ... <many more>

Total time: 4 seconds

我相信如果我能解决 getIndexInfo 问题,那么 GenericJDBCException 就不会发生。我希望这里有人可以帮助我弄清楚如何做到这一点。

这是我的配置和构建文件:

hibernate.cfg.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration SYSTEM
    "classpath://org/hibernate/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>
        <property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
        <property name="hibernate.connection.username">username</property>
        <property name="hibernate.connection.password">password</property>
        <property name="hibernate.connection.url">jdbc:postgresql://localhost:5432/thedb</property>
        <property name="hibernate.connection_pool_size">1</property>
        <property name="hibernate.hbm2ddl.auto">update</property>
        <property name="hibernate.bytecode.use_reflection_optimizer">false</property>
    </session-factory>
</hibernate-configuration>

build.xml:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE project>
<project basedir="." name="HibernateTest">
    <property environment="env" />
    <property name="target" value="1.6" />
    <property name="source" value="1.6" />
    <property name="conf.dir" value="conf" />
    <property name="build.dir" value="src" />
    <path id="properties">
        <dirset dir="${conf.dir}"/>
    </path>
    <path id="toolslib">
        <pathelement location="conf" />
        <pathelement location="lib" />
    </path>
    <taskdef name="hibernatetool" 
      classname="org.hibernate.tool.ant.HibernateToolTask" 
      classpathref="toolslib" />

    <hibernatetool destdir="${build.dir}/generated">
        <jdbcconfiguration 
            packagename="com.test" 
            configurationfile="${conf.dir}/hibernate.cfg.xml" 
            revengfile="${conf.dir}/hibernate.reveng.xml" 
            detectmanytomany="true" />

        <hbm2java ejb3="true" />
    </hibernatetool>
</project>

这是我的 Postgres table 的样子:

                                          Table "public.person"
 Column |         Type          | Collation | Nullable | Default | Storage  | Stats target | Description 
--------+-----------------------+-----------+----------+---------+----------+--------------+-------------
 id     | integer               |           | not null |         | plain    |              | 
 name   | character varying(80) |           |          |         | extended |              | 
Indexes:
    "personpkey" PRIMARY KEY, btree (id)

                                         Table "public.vehicle"
 Column |         Type          | Collation | Nullable | Default | Storage  | Stats target | Description 
--------+-----------------------+-----------+----------+---------+----------+--------------+-------------
 id     | integer               |           | not null |         | plain    |              | 
 name   | character varying(80) |           |          |         | extended |              | 
Indexes:
    "vehiclepkey" PRIMARY KEY, btree (id)

总而言之:为什么休眠工具在尝试从我的 Postgres tables 获取索引信息时遇到异常?

想通了。原来我使用的是过时的 PostgreSQL JDBC 驱动程序,它与我的 PostgreSQL 10 数据库服务器不兼容。用正确的 jar 文件替换它,它现在可以工作了。