Hibernate:如何逆向工程和使用 Postgres 串行类型列?
Hibernate: how to reverse engineer and use a Postgres serial type column?
我在 Postgres 数据库中有以下 table:
CREATE TABLE net.polygon
(
id serial NOT NULL,
x numeric,
y numeric,
CONSTRAINT pk_polygon PRIMARY KEY (id)
);
serial
类型会自动创建一个序列,用于在每次在此 table 中插入新行时创建一个新的主键:
CREATE SEQUENCE net.polygon_id_seq
INCREMENT 1
MINVALUE 1
MAXVALUE 9223372036854775807
START 1
CACHE 1;
我需要从 Java 程序中向此 table 插入数据。我正在使用 Hibernate 对这个数据库进行逆向工程; reveng.xml
文件看起来像:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-reverse-engineering PUBLIC "-//Hibernate/Hibernate Reverse Engineering DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-reverse-engineering-3.0.dtd" >
<hibernate-reverse-engineering>
[...]
<table-filter match-name="polygon"></table-filter>
<table name="polygon">
<primary-key>
<generator class="sequence">
<param name="sequence">polygon_id_seq</param>
</generator>
</primary-key>
</table>
</hibernate-reverse-engineering>
这将为 polygon
table 生成适当的 POJO 和以下映射:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- Generated Feb 15, 2016 9:54:40 AM by Hibernate Tools 4.3.1.Final -->
<hibernate-mapping>
<class name="Polygon" table="polygon" optimistic-lock="version">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="sequence">
<param name="sequence">polygon_id_seq</param>
</generator>
</id>
<property name="x" type="big_decimal">
<column name="x" precision="131089" scale="0" />
</property>
<property name="y" type="big_decimal">
<column name="y" precision="131089" scale="0" />
</property>
</class>
</hibernate-mapping>
在 Java 代码中,新的 Polygon
对象创建如下:
polygon = new Polygon();
polygon.setX(someValue);
polygon.setY(anotherValue);
session.save(polygon);
但它会产生以下异常:
ERROR: relation "net.hibernate_sequence" does not exist
我搜索了代码,但找不到任何对此 hibernate_sequence
关系的引用。如果它是一个序列,为什么 Hibernate 试图使用它而不是 reveng.xml
文件中提供的序列?
更新:Hibernate IRC 的人告诉我这是 Hibernate 工具的问题,is not yet up to date with the latest Hibernate release。
虽然 Hibernate Tools 问题未解决,但可以在 .reveng.xml
文件中使用这种映射将序列与 Eclipse Mars 一起使用:
<table name="entity">
<primary-key>
<generator class="org.hibernate.id.enhanced.SequenceStyleGenerator">
<param name="optimizer">none</param>
<param name="increment_size">1</param>
<param name="sequence_name">entity_id_seq</param>
</generator>
</primary-key>
</table>
此 primary-block
将自动插入到 hbm.xml
文件中:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- Generated Feb 23, 2016 2:14:25 PM by Hibernate Tools 4.3.1.Final -->
<hibernate-mapping>
<class name="Entity" table="entity" optimistic-lock="version">
<id name="idEntity" type="java.lang.Integer">
<column name="id_entity" />
<generator class="org.hibernate.id.enhanced.SequenceStyleGenerator">
<param name="optimizer">none</param>
<param name="sequence_name">entity_id_seq</param>
<param name="increment_size">1</param>
</generator>
</id>
[...]
</class>
</hibernate-mapping>
并且将使用正确的序列(在本例中为 entity_id_seq
)。虽然它需要识别和手动设置每个序列,但此解决方案不需要更改生成的 类 和配置文件,因此它是一次性任务。
我在 Postgres 数据库中有以下 table:
CREATE TABLE net.polygon
(
id serial NOT NULL,
x numeric,
y numeric,
CONSTRAINT pk_polygon PRIMARY KEY (id)
);
serial
类型会自动创建一个序列,用于在每次在此 table 中插入新行时创建一个新的主键:
CREATE SEQUENCE net.polygon_id_seq
INCREMENT 1
MINVALUE 1
MAXVALUE 9223372036854775807
START 1
CACHE 1;
我需要从 Java 程序中向此 table 插入数据。我正在使用 Hibernate 对这个数据库进行逆向工程; reveng.xml
文件看起来像:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-reverse-engineering PUBLIC "-//Hibernate/Hibernate Reverse Engineering DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-reverse-engineering-3.0.dtd" >
<hibernate-reverse-engineering>
[...]
<table-filter match-name="polygon"></table-filter>
<table name="polygon">
<primary-key>
<generator class="sequence">
<param name="sequence">polygon_id_seq</param>
</generator>
</primary-key>
</table>
</hibernate-reverse-engineering>
这将为 polygon
table 生成适当的 POJO 和以下映射:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- Generated Feb 15, 2016 9:54:40 AM by Hibernate Tools 4.3.1.Final -->
<hibernate-mapping>
<class name="Polygon" table="polygon" optimistic-lock="version">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="sequence">
<param name="sequence">polygon_id_seq</param>
</generator>
</id>
<property name="x" type="big_decimal">
<column name="x" precision="131089" scale="0" />
</property>
<property name="y" type="big_decimal">
<column name="y" precision="131089" scale="0" />
</property>
</class>
</hibernate-mapping>
在 Java 代码中,新的 Polygon
对象创建如下:
polygon = new Polygon();
polygon.setX(someValue);
polygon.setY(anotherValue);
session.save(polygon);
但它会产生以下异常:
ERROR: relation "net.hibernate_sequence" does not exist
我搜索了代码,但找不到任何对此 hibernate_sequence
关系的引用。如果它是一个序列,为什么 Hibernate 试图使用它而不是 reveng.xml
文件中提供的序列?
更新:Hibernate IRC 的人告诉我这是 Hibernate 工具的问题,is not yet up to date with the latest Hibernate release。
虽然 Hibernate Tools 问题未解决,但可以在 .reveng.xml
文件中使用这种映射将序列与 Eclipse Mars 一起使用:
<table name="entity">
<primary-key>
<generator class="org.hibernate.id.enhanced.SequenceStyleGenerator">
<param name="optimizer">none</param>
<param name="increment_size">1</param>
<param name="sequence_name">entity_id_seq</param>
</generator>
</primary-key>
</table>
此 primary-block
将自动插入到 hbm.xml
文件中:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- Generated Feb 23, 2016 2:14:25 PM by Hibernate Tools 4.3.1.Final -->
<hibernate-mapping>
<class name="Entity" table="entity" optimistic-lock="version">
<id name="idEntity" type="java.lang.Integer">
<column name="id_entity" />
<generator class="org.hibernate.id.enhanced.SequenceStyleGenerator">
<param name="optimizer">none</param>
<param name="sequence_name">entity_id_seq</param>
<param name="increment_size">1</param>
</generator>
</id>
[...]
</class>
</hibernate-mapping>
并且将使用正确的序列(在本例中为 entity_id_seq
)。虽然它需要识别和手动设置每个序列,但此解决方案不需要更改生成的 类 和配置文件,因此它是一次性任务。