Question

I am using hibernate to do mapping from my java class to oracle tables. For my primary key id, i am using

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

Because my code needs to be run on two machines, i get the following exception very often:

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

That's because I am using hibernate's increment, it tries to again the latest number in memory. Could anyone can show how can i use oracle's auto_increment in hibernate? I add the trigger in database directly, but hibernate crashes when it trying to call 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

Thank you very much!!!!!!!!!

Était-ce utile?

La solution

Oracle doesn't have an auto_increment type. You should use a sequence generator, as shown and explained in this section of the Hibernate reference manual.

Autres conseils

Hibernate actually can read back the value created by a trigger. There are actually 2 ways you can do this:

  1. Use the org.hibernate.id.SequenceIdentityGenerator generator. This works on the JDBC getGeneratedKeys feature, specifically the form allowing to name the columns to be returned. This is highly non-portable across databases. And, in my experience, it is even non-portable across Oracle driver versions (although I have not tried for many years)
  2. Use the org.hibernate.id.SelectGenerator generator. This one works by selecting the identifier column(s) from the just-inserted row using the column(s) of a property defined as unique. You either (a) configure the generator to tell it the unique property, or (b) if you happen to use @NaturalId/ mapping, that is used automatically.

However, "post insert" identifier generators (such as these two as well as IDENTITY generation) often open up a whole new can of worms in terms of impl details for your application. I strongly recommend against using "post insert" identifier generators. You are much better off, IMO, using the sequence generator as discussed in the earlier answer

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top