如果值是由触发器生成的,我如何注释Id列? [英] How do I annotate Id column if value is generated by a trigger?

查看:104
本文介绍了如果值是由触发器生成的,我如何注释Id列?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Oracle XE 10g,Hibernate 3.5,JPA 2.0的设置。有一个带有主键的简单表,由插入时的数据库触发器生成。触发器从序列中获取值。触发器/序列的构造是由Oracle XE完成的。



实际的问题是:如何在EntityManager.persist之后获得实体中Id的当前值?

我试过了:

  @Id 
私人长ID;

- > id是 0 ; < (可插入= false,可更新= false)

私人长ID; 

- > id是 0 ;



  @Id 
@GeneratedValue(strategy = GenerationType.AUTO)
私人长ID;

- >失败,因为Hibernate试图直接查询序列(不存在)。



ID是前两种方法在数据库中生成的,但我的对象中没有该值。与@JB Nizet的评论相反,我可以想到为什么我们让一个触发器分配ID的许多原因:执行存储的过程,手动执行SQL和在Hibernate中运行本机查询,仅举几例。



我个人发现以下解决方案非常令人满意。它让Hibernate找到最大ID并在每次调用插入语句时增加它。但是当语句到达数据库时,ID会被触发器生成的ID忽略和覆盖,所以没有集群问题的唯一性

  @Id 
@GeneratedValue(generator =increment)
@GenericGenerator(name =increment,strategy =increment)
private Long id;

最大的缺点是@GenericGenerator是一个Hibernate注释,所以你失去了JPA的可移植性。程序员也不清楚这个ID实际上是否与一个序列链接。



另一种方法是修改触发器,使其仅在ID为空时递增序列。请参阅使用Oracle触发器生成id的Hibernate问题从一个序列。在大多数情况下,这是最好的解决方案,因为它清楚地显示ID与序列相关联。我唯一的抱怨是,它给了用户/休眠选项来插入任何ID,而无需事先查询序列。


I have a setup with Oracle XE 10g, Hibernate 3.5, JPA 2.0. There is a simple table with a primary key, which is generated by a database trigger at insertion. The trigger gets the value from a sequence. The trigger/sequence construction was made by Oracle XE.

The actual question is: How do I get the current value of the Id in my entity after a EntityManager.persist?
I tried:

@Id
private long id;

-> id is 0;

@Id
@Generated(GenerationTime.ALWAYS)
@Column(insertable = false, updatable = false)
private long id;

-> id is 0;

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private long id;

-> Fails because Hibernate is trying to query the a sequence directly (which does not exist).

IDs are generated in the database in the first two approaches, but I don't have the value in my object.

解决方案

Contrary to @JB Nizet's comments, I can actually think of many reasons why we'd let a trigger assign IDs: execution of stored procs, manual execution of SQLs and running native queries in Hibernate, just to name a few.

I personally found the following solution quite satisfactory. It lets Hibernate find the max ID and have it incremented every time an insert statement is called. But when the statement hits the database, the ID is ignored and overridden by the one generated by the trigger, so there's no uniqueness in a cluster problem:

    @Id
    @GeneratedValue(generator="increment")
    @GenericGenerator(name="increment", strategy = "increment")
    private Long id;

The biggest drawback is @GenericGenerator is a Hibernate annotation, so you lose JPA's portability. It's also not clear to the programmers that this ID is actually linked to a sequence.

Another alternative is to modify the trigger to only increment sequence when ID is null. See "Hibernate issue with Oracle Trigger for generating id from a sequence". In most cases, this is the best solution because it clearly shows the ID is linked to a sequence. My only gripe is it gives user/hibernate the option to insert any ID without actually inquiring the sequence in the first place.

这篇关于如果值是由触发器生成的,我如何注释Id列?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆