1、当使用hibernate连接orcale的时候,仔细看一下生成的ddl,发现最后一句是
create sequence hibernate_sequence;
这是给orcale创建一个sequence,而且所有的表格公用这个sequence。
orcale数据库对于自增的字段,有两种策略,一种是公用这个sequence,一种是每个表使用自己的sequence。
如果在hibernate中配置的是。
<id name="id" type="long" >
<generator class="native" />
</id>
这样,默认会创建公用的sequence,而且名称是hibernate_sequence.
这会有什么问题呢。
在数据库中,每个表中的主键,在自动增加的时候,都是在前一个值的基础上增加。但是这里的前一个值是公用的。例如,有两个表user,role,如果在user中加入了一个记录,他的id现在是1,如果这个时候在role表中加入一个记录role里的id的值是2,而不是1.所有的表在添加记录的时候,都是在2的基础上又开始增加。以上都是第一种策略。
第二种策略中的各自一个sequence,每个表就可以根据自己的id记录,然后增加,互相不会影响。这样的话配置就会麻烦。如
<id name="id" type="long">
<generator class="sequence">
<param name="sequence">type_seq</param>
</generator>
</id>
这里的type_seq只是一个名字,我这里是type是自己的表名。每个表创建这个值的时候不能一样。这样的话在生成ddl语句的时候,你会发现多了这么一句
create sequence type_seq;
这也就是说给type表创建了他的sequence。
这样就解决了hibernate在orcale中自增字段的问题。(这个被139面试的时候,问到了,我当时一点不知道)
2、按照理论上讲,上面两种方式创建的sequence,都可以使用了。但是我在以前一个项目中使用的orcale9i,没有问题。但是现在在使用orcale10i的时候,还是会发现主键自动增加没有成功。在插入一条记录的时候,会提示id为空的错误。
网上找到一种解决方案,就是创建触发器,给每个表添加触发器。如下面:
CREATE TRIGGER type_increaseBEFORE
insert ON js_type FOR EACH ROW
begin
select hibernate_Sequence.nextval into:New.id from dual;
end;
这里给js_type表创建了了触发器,名称为type_increase。按照这种方式每个表都创建触发器。就可以解决了。(下面跟了一篇转载的触发器的介绍)同时如果想删除触发器可以drop trigger type_increase;即可。
但是还是觉得有问题,这样太麻烦了。不知道有没有别的解决办法。先留着这个问题吧。?
示例:
实体BEAN:
@Entity
@Table(name="TZSJGDM")
@SequenceGenerator(name="Tzsjgdm_lsh",sequenceName="HIBERNATE_SEQUENCE")//在类定义中声明序列生成器
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator="Tzsjgdm_lsh")//设置主建的生成方式
@Column(name="LSH")