今天在写一个程序时,发生了件很奇怪的事,以前一直没有注意到。
这次的级联操作我不用hibernate帮我来做,我想自己实现它,所以我在service层的第二个操作之前得到第一个操作的id。
试验几次后,发现hibernate返回来的id与数据库中存的id不一致,差好多,几经研究,终于发现了问题,原来是我在数据库中加了触发器,导致这个问题。
我想大概是这样:
当执行this.getHibernateTemplate().save(obj)时,hibernate执行了三步操作:
1.去数据库中找sequence的下一个值,即应该存入的id
select
backrole_seq.nextval
from
dual
如果在实体类中没有指定是哪个sequence,它会去hibernate_sequence中找,如果不存在此序列,则会无法插入数据。
2.执行实体类的setId方法,将id赋进去.
3.执行sql的save方法。
因此,当数据库中本身存在着触发器时,在执行了sql的save方法之中,数据库本身又改变了它的id。然后才真正地存入到数据库中。
所以当数据库中有触发器时,会导致存入实体之后,再用getId()方法拿到的id并不是数据库中的id,从而影响下一步操作的正确性。
因此呢,我是把数据库中的触发器去掉,然后针对每一个实体类,都定义一个sequence,然后在hibernate层用此数据库建立的sequence就可以了。
@Id
@SequenceGenerator(name="backrole_s",sequenceName="backrole_seq")
@GeneratedValue(generator="backrole_s")
@Column(name="id")
public int getId() {
return id;
}
数据库中:
drop sequence backrole_SEQ;
create sequence backrole_SEQ
minvalue 1
maxvalue 999999999999999999999999999
start with 1
increment by 1
cache 20;