Hibernate + Oracle序列 + 触发器

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?
谢谢
2个回答

13

响应信息位于HIbernate issue with Oracle Trigger for generating id from a sequence

我需要修改我的触发器,仅在没有提供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) 这行代码允许Hibernate手动调用A_SEQ.nextVal来设置ID并绕过触发器,否则Hibernate将无意义地获取nextval,因为触发器总是会再次调用nextval重置ID


1
在你的B类中,你有@GeneratedValue(generator = "preferenceSequence"),但是在你的示例中没有定义它,应该是@GeneratedValue(generator = "bSequence")
默认情况下,Hibernate的分配大小为50,B:IDS=50似乎表明映射选择了错误的序列。

感谢您的回答。我刚刚将preferenceSequence更改为bSequence(复制粘贴错误)。分配大小被强制为1,A的ID和B的ID未连接,给定的值不是真实的,只是为了举例说明。重要的值是A.IDS和B.A_IDS,它们不相等:-/ 祝好 - Valéry Stroeder
你的问题解决了吗?如果是,请将我的回复标记为答案。 - ams
我的问题没有解决,持久调用生成了一个带有错误的“A”ID的“B”实例。正如我在找到的示例中所说,A.ids=10,但B.a.ids=9。 - Valéry Stroeder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接