0

我正在使用hibernate从我的java类映射到oracle表。对于我的主键 ID,我正在使用

<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

那是因为我使用的是休眠的增量,它会再次尝试内存中的最新数字。谁能展示我如何在休眠中使用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

非常感谢你!!!!!!!!!

4

2 回答 2

1

Oracle 没有 auto_increment 类型。您应该使用序列生成器,如Hibernate 参考手册的本节所示和解释。

于 2012-04-03T17:16:54.583 回答
0

Hibernate 实际上可以读回触发器创建的值。实际上有两种方法可以做到这一点:

  1. 使用 org.hibernate.id.SequenceIdentityGenerator 生成器。这适用于 JDBC getGeneratedKeys 功能,特别是允许命名要返回的列的表单。这在数据库之间是高度不可移植的。而且,根据我的经验,它甚至在 Oracle 驱动程序版本之间是不可移植的(尽管我已经很多年没有尝试过了)
  2. 使用 org.hibernate.id.SelectGenerator 生成器。这通过使用定义为唯一的属性的列从刚刚插入的行中选择标识符列来工作。您要么(a)配置生成器以告诉它唯一属性,要么(b)如果您碰巧使用@NaturalId/映射,它会自动使用。

但是,“插入后”标识符生成器(例如这两个以及 IDENTITY 生成器)通常会在您的应用程序的 impl 细节方面打开一个全新的蠕虫罐。我强烈建议不要使用“插入后”标识符生成器。IMO,使用前面答案中讨论的序列生成器,你会好得多

于 2012-06-27T16:02:26.967 回答