一、触发事件
- 在电脑A上敲项目代码,数据库原始资料是直接使用别人写好的sql导入(建表和导入表数据等);
- 将电脑A上数据库的资料,使用PL/SQL Developer导出项目中所用表(此时未导出Oracle数据库的序列user_sequences);
- 将导出的表导入到电脑B的数据库中;
- 在电脑B中运行项目,在持久化某个实例时发生异常 " org.springframework.dao.InvalidDataAccessResourceUsageException: could not get next sequence value; SQL [select SEQ_SYS_JOB.nextval from dual]; nested exception is org.hibernate.exception.SQLGrammarException: could not get next sequence value "
二、知之为知之
广大网友的力量是无穷无尽的,本文相关知识点参考连接:
2.1 什么是sequence
序列(SEQUENCE)实际上是序列号生成器,能够为表中的行自动生成序列号,产生一组等间隔的数值(类型为数字)。
其主要的用途是生成表的主键值,能够在插入语句中引用,也能够经过查询检查当前值,或使序列增至下一个值。
2.2 Hibernate和sequence的关系
咱们已经知道,sequence能够用来生成表中每条记录的主键,这意味着你对于主键的自增加不须要过多地管理,你每添加一个数据,它就会自动为你的主键字段进行赋值。
而Hibernate做为持久化做用的框架,在进行数据保存到表的过程当中,就能够采起sequence方式来做为主键的一种生成策略。固然,
这有两个方面的工做须要你去作:
- 在 *.hbm.xml 中对于你但愿采用sequence序列生成主键的字段,进行配置<generator class ...> (如上图红框标记处)
- 采用数据库提供的sequence机制生成主键,须要数据库支持sequence,如Oralce、DB、SAP DB、PostgerSQL 等,可是MySQL并不支持(可使用identity)
2.3 Oracle中sequence的用法
2.3.1 建立序列
建立序列须要CREATE SEQUENCE系统权限。序列的建立语法以下:
CREATE SEQUENCE 序列名 [INCREMENT BY n] [START WITH n] [{MAXVALUE/ MINVALUE n|NOMAXVALUE}] [CYCLE|NOCYCLE] [{CACHE n|NOCACHE}];
- INCREMENT BY:用于定义序列的步长,若是省略,则默认为1,若是出现负值,则表明序列的值是按照此步长递减的
- START WITH:定义序列的初始值(即产生的第一个值),默认为1
- MAXVALUE:定义序列生成器能产生的最大值。选项NOMAXVALUE是默认选项,表明没有最大值定义
- MINVALUE:定义序列生成器能产生的最小值。选项NOMAXVALUE是默认选项,表明没有最小值定义
- CYCLE 和 NOCYCLE:表示当序列生成器的值达到限制值后是否循环,CYCLE表明循环,NOCYCLE表明不循环。若是不循环,达到限制值后,继续产生新值就会发生错误
- CACHE 和 NOCACHE:定义存放序列的内存块的大小,默认为20。NOCACHE表示不对序列进行内存缓冲。对序列进行内存缓冲,能够改善序列的性能
2.3.2 查看序列
SELECT * FROM USER_SEQUENCES;
2.3.3 删除序列
2.4 解决异常could not get next sequence value
在使用hibernate保存数据的时候,出现了could not get next sequence value这个错误,这个错误的意思就是找不到序列中的下一个值.
那么你须要作的是:
- 肯定主键生成策略,到相应的表的 *.hbm.xml文件查看指明使用了的是哪一个sequence(如本例图中所示的 SEQ_SYS_JOB)
- 登陆Oracle数据库,而后查看该用户下是否存在该指明的sequence(SELECT * FROM USER_SEQUENCES;)
- 若是没有sequence,则须要到相应的用户下的建立该sequence(CREATE SEQUENCE 序列名;)
- 若是该数据表中已经有值的话,仍是会出现上面那个问题,由于sequence的CURRVAL值可能不符合next value(详见 link-1、link-2)
最终,异常就这样解决了,皆大欢喜。