java - 在 Oracle 和 Hibernate 中使用 ID 列序列会创建奇怪的(负)值

标签 java oracle hibernate

我正在尝试学习 Hibernate 和 JPA 与 Oracle 数据库的使用。

这就是我到目前为止所拥有的。

表和序列声明

CREATE TABLE MESSAGE( ID    INTEGER NOT NULL PRIMARY KEY,
                      Text  VARCHAR2( 255 ) NOT NULL );

CREATE SEQUENCE Message_Seq START WITH 1 INCREMENT BY 1;

hibernate.cfg.xml

<hibernate-configuration>
<session-factory>

    <!-- Database connection settings -->
    <property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
    <property name="hibernate.connection.password">tbi</property>
    <property name="hibernate.connection.url">jdbc:oracle:thin:@LHT:3100/LHT0</property>
    <property name="hibernate.connection.username">tbi</property>
    <property name="hibernate.default_schema">tbi</property>

    <!-- SQL dialect -->
    <property name="hibernate.dialect">org.hibernate.dialect.Oracle8iDialect</property>

    <!-- Echo all executed SQL to stdout -->
    <property name="show_sql">true</property>

    <!-- Mapping class -->
    <mapping class="entity.Message"/>
</session-factory>

实体类

package entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;

@Entity
@Table(name = "message")
public class Message {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "id_Sequence")
    @SequenceGenerator(name = "id_Sequence", sequenceName ="Message_Seq")
    @Column(name = "ID")
    private Long id;

    @Column(name = "TEXT")
    private String text;

    public Message() {
    }

    public Message(String text) {
        this.text = text;
    }

    @Override
    public String toString() {
        return "Message [id=" + id + ", text=" + text + "]";
    }

}

客户端类

package client;

import org.hibernate.Session;
import util.HibernateUtil;
import entity.Message;

public class HelloWorldClient {

    public static void main(String[] args) {

        Session session = HibernateUtil.getSessionFactory().openSession();
        session.beginTransaction();

        Message message = new Message("Hello, World!");

        session.save(message);

        session.getTransaction().commit();
        session.close();

}

}

如果我执行此命令,我第一次在控制台中看到它作为 SQL 输出:

Hibernate: select tbi.Message_Seq.nextval from dual
Hibernate: select tbi.Message_Seq.nextval from dual
Hibernate: insert into tbi.message (TEXT, ID) values (?, ?)

注意序列调用是如何完成两次的。

表格如下所示:

SELECT *
FROM   MESSAGE;

ID  Text
--  -------------
1   Hello, World!

SELECT Message_Seq.NEXTVAL
FROM   DUAL;

NEXTVAL
-------
3

如果我第二次执行示例,我会看到以下控制台输出:

Hibernate: select tbi.Message_Seq.nextval from dual
Hibernate: insert into tbi.message (TEXT, ID) values (?, ?)

注意一次序列调用是如何完成的。

SELECT *
FROM   MESSAGE;

ID  Text
--- -------------
1   Hello, World!
-45 Hello, World!

SELECT Message_Seq.NEXTVAL
FROM   DUAL;

NEXTVAL
-------
5

nextval 计数正确,但 -45 作为 ID 是从哪里来的?

这一切从那里继续下去:

ID  Text
--- -------------
1   Hello, World!
-43 Hello, World!
-44 Hello, World!
-45 Hello, World!

说实话,我现在很困惑。

最佳答案

评论中 TechEnthusiast 的暗示起到了作用。

您必须设置

<property name="hibernate.id.new_generator_mappings">false</property>

在您的 Hibernate 配置中,并告诉 hibernate 增加序列,就像您在 Oracle 数据库上配置序列一样,例如: G。如果你设置了

INCREMENT BY 1

在您的数据库 ddl 中,您需要

allocationSize=1

相应地在实体 bean 的 @SequenceGenerator 注释中。

关于java - 在 Oracle 和 Hibernate 中使用 ID 列序列会创建奇怪的(负)值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41724838/

相关文章:

Java boolean 值不从类传递

oracle - 是否可以在列表分区表中自动创建新分区?

java - 将条件放入 'OR' 条件的列表中

触发了 hibernate 实体拦截器但设置值不保存

oracle函数,如excel中的days360

java - JPA CreateNativeQuery 返回错误的日期

java - new BigInteger(String) 发出 Sonar 警告

java - 根据 sn 和给定名称的 3 个字符动态分配唯一的 UID 值

java - 如何在Java中实现接口(interface)方法

Oracle sqldeveloper - 如何从命令行连接数据库