7

我有一个表,其索引由使用序列的触发器自动填充(Oracle 数据库)

CREATE TABLE A
(
  IDS                           NUMBER(10)      NOT NULL
)


CREATE OR REPLACE TRIGGER A_TRG
BEFORE INSERT
ON A REFERENCING NEW AS New OLD AS Old
FOR EACH ROW
BEGIN
  :new.IDS := A_SEQ.nextval;
END A_TRG;
/

我有一个匹配的 Java 类:

Class A {
   @Id
   @SequenceGenerator(name = "aSequence", sequenceName = "A_SEQ", allocationSize = 1)
   @GeneratedValue(generator = "aSequence", strategy = GenerationType.SEQUENCE)
   @Column(name = "IDS")
   Long id;

   ...
}

当我尝试像这样持久化 A 的实例时:

EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
A a = new A();
Long id = getHibernateTemplate().save(a);
transaction.commit();

我遇到了这个问题:

  • 保存调用返回的代码中的 ID = "X"

  • 数据库中的 ID = "X+1"

有没有办法设置 Hibernate 让数据库触发器创建 ID?

谢谢

4

2 回答 2

13

在 Oracle Trigger 的 HIbernate 问题中找到响应,用于从序列生成 id

我需要调整我的触发器以仅在没有给出 ID 时运行:

CREATE OR REPLACE TRIGGER A_TRG
BEFORE INSERT
ON A REFERENCING NEW AS New OLD AS Old
FOR EACH ROW
WHEN (New.IDS is null) -- (1)
BEGIN
  :new.IDS := A_SEQ.nextval;
END A_TRG;
/

(1) this line allow Hibernate to manually call A_SEQ.nextVal to set the ID and then bypass the trigger else Hibernate will get the nextval for uselessly because the trigger will always reset the ID calling nextval again

于 2012-11-20T10:23:14.830 回答
1

在您的 B 类@GeneratedValue(generator = "preferenceSequence")中,您拥有的示例中没有定义,它应该是 @GeneratedValue(generator = "bSequence")

默认情况下,休眠分配大小为 50 B: IDS=50 似乎表明映射选择了错误的序列。

于 2012-11-17T19:52:22.907 回答