2012-04-03 55 views
0

我使用hibernate將映射從我的java類映射到oracle表。對於我的主鍵ID,我使用在休眠狀態下使用oracle自動增量觸發

<generator class="increment"></generator> 

由於需要在兩臺機器上運行我的代碼,我得到了非常頻繁以下異常:

java.util.concurrent.ExecutionException: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update 

Caused by: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update 
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:96) 
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66) 
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275) 
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:268) 
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:184) 
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321) 
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51) 
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216) 
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383) 
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133) 
at jobsrc.BasicDaoImpl.save(BasicDaoImpl.java:65) 

Caused by: java.sql.BatchUpdateException: ORA-00001: unique constraint (DB.SYS_C0011343) violated 

at oracle.jdbc.driver.DatabaseError.throwBatchUpdateException(DatabaseError.java:343) 
at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10700) 
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeBatch(NewProxyPreparedStatement.java:1723) 
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70) 
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268) 
... 18 more 

那是因爲我使用Hibernate的增量,它會嘗試重新記憶內存中的最新數字。任何人都可以顯示如何在休眠狀態下使用oracle的auto_increment? 我添加了觸發直接的數據庫,但冬眠崩潰時,它試圖調用saveOrUpdate:

org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update 
at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:140) 
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:128) 
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66) 
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275) 
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:268) 
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:184) 
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321) 
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51) 
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216) 
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383) 
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133) 
at jobsrc.BasicDaoImpl.saveOrUpdate(BasicDaoImpl.java:37) 

Caused by: java.sql.BatchUpdateException: No more data to read from socket 
at oracle.jdbc.driver.DatabaseError.throwBatchUpdateException(DatabaseError.java:343) 
at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10700) 
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeBatch(NewProxyPreparedStatement.java:1723) 
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70) 
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268) 
... 13 more 

非常感謝!!!!!!!!!

回答

1

Oracle沒有auto_increment類型。您應該使用序列生成器,如this section of the Hibernate reference manual中所示和說明。

+0

我的意思是直接在數據庫中使用觸發器 – 2012-04-03 18:21:50

+0

AFAIK,現在有辦法讓Hibernate獲取觸發器產生的值。這是一個雞和雞蛋問題:要獲得生成的密鑰,您需要生成的密鑰。使用序列。 – 2012-04-03 18:24:40

+0

我嘗試了序列,值跳轉 – 2012-04-03 18:27:18

0

Hibernate實際上可以讀回由觸發器創建的值。實際上有兩種方法可以做到這一點:

  1. 使用org.hibernate.id.SequenceIdentityGenerator生成器。這適用於JDBC getGeneratedKeys功能,特別是允許命名要返回的列的表單。這在數據庫中是非常不可移植的。並且,根據我的經驗,它甚至在Oracle驅動程序版本中不可移植(雖然我多年沒有嘗試過)
  2. 使用org.hibernate.id.SelectGenerator生成器。這項工作是通過使用定義爲唯一的屬性的列從剛剛插入的行中選擇標識符列進行的。您可以(a)將生成器配置爲告訴其唯一屬性,或者(b)如果您恰好使用@ NaturalId/mapping,則自動使用該屬性。

但是,「後插入」標識符生成器(例如這兩個以及IDENTITY世代)經常會爲您的應用程序打開一整套新的蠕蟲。我強烈建議不要使用「後插入」標識符生成器。你的情況要好得多,國際海事組織,使用前面的回答中討論的序列發生器