【问题标题】:Hibernate: how to reverse engineer and use a Postgres serial type column?Hibernate:如何逆向工程和使用 Postgres 串行类型列?
【发布时间】:2016-05-26 03:13:32
【问题描述】:

我在 Postgres 数据库中有下表:

CREATE TABLE net.polygon
(
  id serial NOT NULL,
  x numeric,
  y numeric,
  CONSTRAINT pk_polygon PRIMARY KEY (id)
);

serial 类型会自动创建一个序列,用于在此表中每次插入新行时创建一个新的主键:

CREATE SEQUENCE net.polygon_id_seq
  INCREMENT 1
  MINVALUE 1
  MAXVALUE 9223372036854775807
  START 1
  CACHE 1;

我需要从 Java 程序向此表中插入数据。我正在使用 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 表生成适当的 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);

但它会产生以下异常:

错误:关系“net.hibernate_sequence”不存在

我已经搜索了代码,但找不到任何对此hibernate_sequence 关系的引用。如果是序列,为什么 Hibernate 尝试使用它而不是 reveng.xml 文件中提供的序列?

更新:Hibernate IRC 的人们告诉我这是 Hibernate 工具的问题,is not yet up to date with the latest Hibernate release

【问题讨论】:

  • 这很奇怪。您是否尝试过干净构建您的项目?
  • 是的,但错误仍然存​​在。

标签: hibernate postgresql reverse-engineering


【解决方案1】:

虽然 Hibernate Tools 问题没有解决,但序列可以在 Eclipse Mars 中使用.reveng.xml 文件中的这种映射:

<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)。虽然需要识别和手动设置每个序列,但该解决方案不需要更改生成的类和配置文件,因此是一次性任务。

【讨论】:

    猜你喜欢
    • 2011-03-13
    • 2015-02-11
    • 1970-01-01
    • 2021-05-14
    • 2012-03-15
    • 1970-01-01
    • 2014-06-25
    • 2012-03-10
    • 1970-01-01
    相关资源
    最近更新 更多