一、觸發事件
- 在電腦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)
最終,異常就這樣解決了,皆大歡喜。