我正在尝试学习 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/