Hi all,
I am having trouble on getting the sequence mechanism work for HSQLDB. So here are the versions I use:
Hibernate-Version: 3.2.2.ga
HSQLDB: 1.8.0
The story is like this; I created a sequence in my database using this line of code:
Code:
CREATE SEQUENCE MIT_SEQ AS INTEGER
START WITH 1 INCREMENT BY 1;
I have an entity named Mitarbeiter. So, what I want to do is to get the id for this entity by fetching the next value of MIT_SEQ in case of an insert operation.
I mapped my entity as follows:
Code:
<class name="Mitarbeiter" table="MITARBEITER" schema="PUBLIC">
<id name="id" column="MIT_ID" type="int" access="field">
<generator class="sequence">
<param name="sequence">MIT_SEQ</param>
</generator>
</id>
...
...
However, when I try to let my Mitarbeiter object inserted, I see that the next value of MIT_SEQ is tried to be fetched using a temporary table (dual_mit_seq) and a select for it.
Code:
final MitarbeiterIfc m = Mitarbeiter.getInstance(MAENNLICH, "Rocky", "Balboa");
try {
tx = HibernateUtil.getSessionFactory().openSession().beginTransaction();
tx.setTimeout(5);
// Save the PO
getSession().save(m);
tx.commit();
} catch (RuntimeException e) {
try {
tx.rollback();
} catch (RuntimeException e1) {
log.error(" Rollback failed ", e1);
}
throw e;
}
Here's the concerning logging part:
------------------------------------------
WARN - SQL Error: -22, SQLState: S0002
ERROR - Table not found in statement [select next value for MIT_SEQ from dual_MIT_SEQ]
Exception in thread "main" org.hibernate.exception.SQLGrammarException: could not get next sequence value
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:67)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.id.SequenceGenerator.generate(SequenceGenerator.java:96)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:99)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:187)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:172)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:94)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:507)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:499)
at org.hibernate.engine.CascadingAction$1.cascade(CascadingAction.java:218)
at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:268)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:216)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:296)
at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:242)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:219)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
at org.hibernate.engine.Cascade.cascade(Cascade.java:130)
at org.hibernate.event.def.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:131)
at org.hibernate.event.def.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:122)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:65)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at de.alpercelik.uebungen.acmeag.controller.Tester.neuMitarbeiterVw(Tester.java:188)
at de.alpercelik.uebungen.acmeag.controller.Tester.main(Tester.java:49)
Caused by: java.sql.SQLException: Table not found in statement [select next value for MIT_SEQ from dual_MIT_SEQ]
at org.hsqldb.jdbc.Util.throwError(Unknown Source)
at org.hsqldb.jdbc.jdbcPreparedStatement.<init>(Unknown Source)
at org.hsqldb.jdbc.jdbcConnection.prepareStatement(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at com.mchange.v2.c3p0.stmt.GooGooStatementCache$1StmtAcquireTask.run(GooGooStatementCache.java:525)
at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)
------------------------------------------
I search this problem in the forums but didn't find a proper solution for me. There are some ways in which the HSQLDialect.getSequenceNextValString() is overridden etc. But I think what I want to do must not be so tricky. The sequence on an HSQLDB does not necessarily need any temporary table like dual_mit_seq and the required next value could easily be fetched by using:
Code:
insert into mitarbeiter(mit_id, mit_name,...) values (next value for mit_seq, 'John',...)
I wonder why my mapping setup doesn't create such a simple code and deal with some extra dual_mit_seq tables instead. Can anybody explain me what I am doing wrong and what the correct way would be?
Thanks in advance!
Cheers,
Alper