-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 
Author Message
 Post subject: Generator="increment" problems
PostPosted: Wed Aug 30, 2006 10:45 am 
Newbie

Joined: Wed Aug 30, 2006 10:15 am
Posts: 3
HI!
I have some problems with this kind of Id generator - I save a newly created object in the session, and then I commit the transaction and close the current session. Then for the purpose of the generation of the new id, hibernate selects the max ID and inserts a new record in the DB. But sometimes Hibernate doesn't print the "select max" query in the console... And rarely there are exceptions because of the insertion of a new record having the same primary key as an old one. I don't try to set the primary key anywhere and on every call to the method I open a new session and then close it in a "finally" block before the method returns. Are there some caching options I have to set, so hibernate selects the max ID of an entity every time, before inserting it in the DB?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 30, 2006 10:59 am 
Newbie

Joined: Wed Aug 30, 2006 10:15 am
Posts: 3
17:48:52,922 WARN [JDBCExceptionReporter] Database selected
17:48:52,938 INFO [STDOUT] Hibernate: select this_.id as id13_0_, this_.office_code as office2_13_0_, this_.name as name13_0_ from seed.nd_office...
17:48:52,953 INFO [STDOUT] Hibernate: insert into seed.nd_registered_trader ...

In the first select, I select an "office" that will be later connected to the main entity, "registered trader". Then,in the application I connect the newly created registered trader to the office and call session.save() for the trader. I select the office trough a Criteria created by the same session, so it's in persistent state. The code looks something like this:

office.getNdRegisteredTrader().add(registeredTrader);
registeredTrader.setOffice(office);
currentSession.save(registeredTrader);

The "select max id" query is not printed, and then I get the following exception:

17:48:53,063 ERROR [JDBCExceptionReporter] ISAM error: duplicate value for a record with unique key.
17:48:53,063 ERROR [AbstractFlushingEventListener] Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: could not insert: [com.itt.ems.seed.dto.nd.NdRegisteredTrader]
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2078)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2427)
at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:51)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:248)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:232)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:139)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:297)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:985)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:333)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 30, 2006 11:51 am 
Newbie

Joined: Wed Aug 30, 2006 10:15 am
Posts: 3
Never mind guys, i found the source of the problem - There is another server connected to the same DB running the same application and the book "Hibernate in action" says about the "increment" generator:
"At Hibernate startup, this generator reads the maximum primary key column value
of the table and increments the value by one each time a new row is inserted. The
generated identifier is of type long, short, or int. This generator is especially
efficient if the single-server Hibernate application has exclusive access to the
database but shouldn’t be used in any other scenario."
And my scenario is the "any other" one. So, at first Hibernate caches the ID of the table and on later inserts doesn't select the max ID. But if another server connects to the DB and inserts a record, the cached ID of the first Hibernate instance becomes invalid. So when i insert a new record after that - BOOM, and there it is - the duplicate key exception!
So there is my suggestion - a user should have the possibility to decide whether Hibernate should cache the Id or to select the max id on every insert. Because, if I have a transaction that locks the table and inserts many records into it - there will be just one "select max id" query each time I commit a transaction and the "select max ID" query won't be a big drawback in this case.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.