2009-09-09 32 views
3

基本上,我想要一種以數據庫中立的方式訪問序列值的方法。 用例是我在一個實體上有一個字段,我想根據遞增值(不是id)來設置。手動使用Hibernate序列生成器

例如,假設我有一個Shipment實體。在貨物創建後的某個時間點,它會被運送。一旦出貨,就會爲其生成清單編號並進行分配。清單編號看起來像M000009(其中'M'之後的內容是來自序列的左側填充值)。

類似的東西被問到here at SO,但我不是解決方案的粉絲,因爲它需要另一張桌子來維護,似乎是一個奇怪的關係。

有沒有人知道是否有可能使用諸如休眠的MultipleHiLoPerTableGenerator之類的東西作爲ID發生器以外的東西?

如果這是不可能的,是否有人知道任何處理這個問題的庫(使用hibernate或甚至純粹的JDBC)。我寧願不必自己寫這個(並且必須處理預取值,鎖定和同步)。

謝謝。

回答

1

我覺得你的任務的複雜性取決於你貨單號是否需要按順序排列:

  • 如果您不需要順序清單數字那麼它是快樂的日子和可以使用序列。
  • 如果您確實需要順序清單號碼(或者您的數據庫不支持序列),那麼使用帶有適當鎖定的id表,以便每個事務獲得唯一的連續值。

那麼你已經有了,我能想到的2種選擇:

  • 編寫客戶端上進行必要的JDBC代碼,以確保(如果貨單號是連續的)正在使用的交易是與數據庫更新相同。
  • 使用觸發器在發生適當更新時創建清單編號。

我認爲我的偏好是觸發器,因爲事務的事務方面將被照顧,儘管這意味着對象需要刷新客戶端。

1

我沒有閱讀鏈接的類似解決方案,但聽起來像我最終做的事情。我爲序列創建了一個表格。我爲每個需要的序列類型添加了一行表格。

然後我有一個序列生成器類,它將執行必要的sql查詢來獲取和更新特定命名序列的序列值。

我用hibernate的Dialect類以db中立的方式做它。

我也會'緩存'的序列。我會將大量存儲的序列值碰撞,然後從我的生成器類中分配那些分配的序列。如果該類被銷燬(即應用程序關閉),則序列生成器的新實例將以所存儲的值啓動。 (在我的序號中有空位並不重要)

1

這是一個代碼samnple。我想告誡這一點 - 我沒有聲明這一點,它需要春天的代碼。說了這些之後,它仍然應該提供你想要做的事情的骨骼。

public Long getManifestNumber() { 
     final Object result = getHibernateTemplate().execute(new HibernateCallback() { 
      public Object doInHibernate(Session sess) throws HibernateException, SQLException { 
       SQLQuery sqlQuery = sess.createSQLQuery("select MY_SEQUENCE.NEXTVAL from dual"); 
       sqlQuery.uniqueResult(); 
      } 
     }); 
     Long toReturn; 
     if (result instanceof BigDecimal) { 
      toReturn = ((BigDecimal)result).longValue(); 
     } 
     return toReturn; 
    }