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 文件替换它,它现在可以工作了。
我正在使用 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 文件替换它,它现在可以工作了。