警告信息以下: java
3.1 WARN [org.hibernate.id.UUIDHexGenerator] (ServerService Thread Pool -- 48) HHH000409:Using org.hibernate.id.UUIDHexGenerator which does not generate IETF RFC 4122 compliant UUID values; consider using org.hibernate.id.UUIDGenerator instead sql
修改 @GenericGenerator(name = "system-uuid", strategy = "uuid") 爲@GenericGenerator(name = "system-uuid", strategy = "uuid2") 數據庫
下面是在CSDN上看到的一篇文章,保存在個人txt中,如今也貼出來. api
介紹hibernate主鍵生成策略的文章網上比比皆是。可是如何選擇一個適合於本身項目的主鍵生成策略缺沒有什麼好的指導性文章。在此但願與你們議論。
hibernate的主鍵生成策略主要包括了"uuid2","guid","uuid","uuid.hex","hilo","assigned","identity","select","sequence","seqhilo","increment","foreign","sequence-identity","enhanced-sequence","enhanced-table",所有在org.hibernate.id.factory.DefaultIdentifierGeneratorFactory中定義,至於每種生成策略的簡單描述不是本文重點議論的話題,咱們主要將着眼點放到各生成器的優缺點上去(固然都有優勢只是適合不適合,本文就想議論這個)
hibernate主鍵生成採用策略模式進行設計,各個生成策略都直接或或者間接實現了IdentifierGenerator接口,此接口只有一個方法publicSerializablegenerate(SessionImplementorsession,Objectobject)throwsHibernateException;這個方法由各個類實現具體的生成邏輯。
咱們來一個一個看一下: 緩存
一、uuid2,IdentifierGenerator的實現類是UUIDGenerator,具體由UUIDGenerationStrategy策略負責生成,它有兩個實現StandardRandomStrategy和CustomVersionOneStrategy,他們都是使用java.util.UUID的api生成主鍵的,StandardRandomStrategy最終由UUID.randomUUID();生成,而CustomVersionOneStrategy則採用版本號與位運算經過構造函數newUUID(mostSignificantBits,leastSignificantBits);生成。
特色是:不須要和數據庫交互,可根據RFC4122定義的5中變量控制具體的生成策略(由於符合RFC4122定義,因此避免了警告信息)
二、guid,IdentifierGenerator的實現類是GUIDGenerator,經過session.getFactory().getDialect().getSelectGUIDString();得到各個數據庫中的標示字符串,mySql用"selectuuid()";oracle9g用return"selectrawtohex(sys_guid())fromdual";其餘看源碼吧。
特色是:須要和數據庫進行一次查詢才能生成。數據庫全局惟一。
三、uuid和uuid.hex 兩個一個東西。IdentifierGenerator的實現類是UUIDHexGenerator,經過StringBuffer(36).append(format(getIP())).append(sep).append(format(getJVM())).append(sep).append(format(getHiTime())).append(sep).append(format(getLoTime())).append(sep).append(format(getCount()))生成。
特色:不須要和數據庫交互,全網惟一。
四、hilo,IdentifierGenerator的實現類TableHiLoGenerator,邏輯較爲複雜,經過高低位酸腐生成,可是須要給定表和列做爲高值的源。加上本地的地位計算所得。複雜有興趣看"數據建模101"(Ambler,2002)
特色;須要和數據庫交互,全數據庫惟一,與guid不一樣的是,在標識符的單個源必須被多個插入訪問時能夠避免擁堵。
五、assigned IdentifierGenerator的實現類Assigned,沒有生成邏輯,若是爲空就拋出異常。
特色:不須要和數據庫交互,本身管理主鍵生成,顯示的指定id.
六、identity,IdentityGenerator並無直接實現IdentifierGenerator,而是擴展了AbstractPostInsertGenerator,並實現PostInsertIdentifierGenerator,而PostInsertIdentifierGenerator實現了IdentifierGenerator. 經過IdentifierGeneratorHelper類生成,這個比較特殊,它返回是個常量"POST_INSERT_INDICATOR",指在數據庫插入後時生成,而後返回數據庫生成的id,還有個常量"SHORT_CIRCUIT_INDICATOR",是用外鍵ForeignGenerator時使用的。
特色:須要和數據庫交互,數據插入後返回(反查)id,同一列惟一
七、select, SelectGenerator擴展了AbstractPostInsertGenerator實現了Configurable接口,而AbstractPostInsertGenerator實現了PostInsertIdentifierGenerator。因此具備和identity相似的行爲,有數據庫觸發器生成。
特色:須要和數據庫交互,
八、sequence,SequenceGenerator實現了PersistentIdentifierGenerator接口,和Configurable接口,PersistentIdentifierGenerator接口擴展IdentifierGenerator接口,經過數據庫不一樣獲取不一樣的取值語句dialect.getSequenceNextValString( sequenceName );而後進行查詢,緩存到IntegralDataTypeHolder中,經過generateHolder( session ).makeValue();得到。
特色:須要和數據庫交互(但不是每次都是)。sequence惟一
九、seqhilo,擴展了SequenceGenerator,處理邏輯和hilo相同,值不過是使用一個具名的數據庫序列來生成高值部分。
特色:同4
十、increment,IdentifierGenerator的實現類IncrementGenerator,並實現了Configurable接口。數據庫啓動時查詢表的最大主鍵列支,並經過IntegralDataTypeHolder緩存。插入一條,它自加一。
特色:僅須要首次訪問數據庫。
十一、foreign,IdentifierGenerator的實現類ForeignGenerator,經過給定的entityName和propertyName查詢得到值。
特色:須要和數據庫訪問。
後面的幾種基本上是上面各類邏輯的組合,不在一一分析了。enhanced-table是經過數據庫中的表生成id的。
從上面能夠看到,雖然這麼多,可是大致能夠分爲三類
一、不須要和數據庫交互就能夠生成id的。包括uuid,uuid2,uuid.hex
二、須要和數據庫交互以生成id的。guid,hilo,identity,select,sequence,seqhilo,increment、foreign
可細分爲一個id一個sql:guid,identity,select,foreign
一個sql多個id:hilo,sequence,seqhilo,increment
三、不用交互我本身管理assigned
提升系統新能的主要作法就是顯著減小數據庫的訪問次數。經過上面的分析,可做爲咱們考慮的一個指標。
你們議論下,本身項目中的主鍵生成是什麼策略,以及優缺點是什麼?
這是爲csdn的大牛ldh911的議論如下繼續
◎ 關於ID生成
—— 我一向認爲入手都是Assigned,也就是說我考慮的方式是:若是我本身來生成這個ID的話,最優選擇是啥?而後再看看Hibernate之類的是否能提供我最優選擇所指望的。
—— 是否集羣環境?是第一個要考慮的因素,但基本上我都以集羣環境爲必要條件;
—— 而後是:超高併發生成?超高併發查詢?ID是否須要存在語義?等問題。
◎ 不一樣的ID對我來講有啥區別?
—— UUID:極其適用於分佈式計算環境(超越集羣了),但ID將不能承載任何語義,高併發生成支持較好,超高併發查詢存在數據庫端不易優化的問題。
—— 數據庫端seq:適用於集羣環境,ID可承載某些語義(好比生成時間上較大範圍的前後順序),超高併發生成較搓,超高併發查詢可作特定分區優化。
◎ 最終呢?
—— 最終基本上都選擇UUID或其變體,由於有時候我仍是須要ID承載少許語義的,好比我可能會關心這個UUID到底是哪一個終端生成的,你可能會說:能夠換個字段保存啊?這類問題就智者見智仁者見仁了。 session