I know I'm off the beaten path here, but I've been using Hibernate against Access with a good amount of success. Access 2000+ even supports "@@identity" so I am now trying to get native id generation working.
The problem is this "ResultSet is closed" exception (pasted below).
I stepped through the Hibernate code and actually found "rs.close" being called twice ...once in IdentifierGeneratorFactory:40 and then again in AbstractPostInsertGenerator:47. This second time it is called causes the "ResultSet is closed" exception.
This seems strange as AbstractPostInsertGenerator "owns" the ResultSet as it creates it from a prepared statement and I think it makes sense for it to have the responsibility to close it as well, But then this IdentifierGeneratorFactory goes off and closes the result set it gets in as a parameter - which seems to violate the no-side effects principle.
Looking at ViewCVS, The IdentifierGeneratorFactory code is also somewhat new, so I'm thinking it calling rs.close is just a mistake. I just removed it and now saving objects to Access works perfectly.
This is a show-stopper bug for me but I'm surprised it made it into 3.0-rc1...my only thought is that maybe the JDBC-ODBC bridge I'm using to get to Access is being overly picky about rs.close being called twice while other drivers like MySQL, etc., just ignore the second call.
I'd like to file this as a bug in Jira but am following directions and bringing it up here first. Let me know what I should do. Thanks.
Patch:
--- IdentifierGeneratorFactory.java.orig Sun Mar 06 17:44:07 2005
+++ IdentifierGeneratorFactory.java Sun Mar 06 17:46:15 2005
@@ -30,15 +30,10 @@
public static Serializable getGeneratedIdentity(ResultSet rs, Type type)
throws SQLException, HibernateException, IdentifierGenerationException {
final Serializable id;
- try {
- if ( !rs.next() ) {
- throw new HibernateException( "The database retu
rned no natively generated identity value" );
- }
- id = IdentifierGeneratorFactory.get( rs, type );
- }
- finally {
- rs.close();
- }
+ if ( !rs.next() ) {
+ throw new HibernateException( "The database returned no natively ge
nerated identity value" );
+ }
+ id = IdentifierGeneratorFactory.get( rs, type );
if ( log.isDebugEnabled() ) log.debug( "Natively generated ident
ity: " + id );
return id;
}
Hibernate version:
3.0-rc-1
Full stack trace of any exception that occurs (with original IdentifierGeneratorFactory):
[2005-03-06 17:26:20,838] [DEBUG] (org.hibernate.jdbc.AbstractBatcher.java:258) - [about to open PreparedStatement (open PreparedStatements: 0, globally: 3)]
[2005-03-06 17:26:20,838] [DEBUG] (org.hibernate.jdbc.AbstractBatcher.java:292) - [select @@identity;]
[2005-03-06 17:26:20,838] [DEBUG] (org.hibernate.jdbc.AbstractBatcher.java:343) - [preparing statement]
[2005-03-06 17:26:20,838] [DEBUG] (org.hibernate.id.IdentifierGeneratorFactory.java:42) - [Natively generated identity: 6105]
[2005-03-06 17:26:20,848] [DEBUG] (org.hibernate.jdbc.AbstractBatcher.java:266) - [about to close PreparedStatement (open PreparedStatements: 1, globally: 4)]
[2005-03-06 17:26:20,848] [DEBUG] (org.hibernate.jdbc.AbstractBatcher.java:363) - [closing statement]
[2005-03-06 17:26:20,858] [DEBUG] (org.hibernate.util.JDBCExceptionReporter.java:49) - [could not insert: [com.uprr.app.hss.vo.CaseStatusLinkVO] [select @@identity;]]
java.sql.SQLException: ResultSet is closed
at sun.jdbc.odbc.JdbcOdbcResultSet.checkOpen(JdbcOdbcResultSet.java:6650)
at sun.jdbc.odbc.JdbcOdbcResultSet.clearWarnings(JdbcOdbcResultSet.java:1767)
at sun.jdbc.odbc.JdbcOdbcResultSet.close(JdbcOdbcResultSet.java:1470)
at org.apache.commons.dbcp.DelegatingResultSet.close(DelegatingResultSet.java:193)
at org.hibernate.id.AbstractPostInsertGenerator.getGenerated(AbstractPostInsertGenerator.java:47)
at org.hibernate.persister.entity.BasicEntityPersister.insert(BasicEntityPersister.java:1755)
at org.hibernate.persister.entity.BasicEntityPersister.insert(BasicEntityPersister.java:2149)
at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:34)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:239)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:238)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:158)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:104)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:184)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:173)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:96)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:69)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:416)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:411)
at com.uprr.app.hss.dao.hibernate.BaseHibernateDAOImpl$4.handle(BaseHibernateDAOImpl.java:109)
at com.uprr.app.hss.dao.hibernate.BaseHibernateDAOImpl.executeSessionHandler(BaseHibernateDAOImpl.java:137)
at com.uprr.app.hss.dao.hibernate.BaseHibernateDAOImpl.save(BaseHibernateDAOImpl.java:107)
at com.uprr.app.hss.dao.hibernate.CaseStatusLinkHibernateDAOImpl.addNewLink(CaseStatusLinkHibernateDAOImpl.java:23)
at com.uprr.app.hss.dao.CaseStatusLinkDAOTest.testAddNewLink(CaseStatusLinkDAOTest.java:28)
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:324)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:421)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:305)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:186)
[2005-03-06 17:26:20,858] [WARN] (org.hibernate.util.JDBCExceptionReporter.java:57) - [SQL Error: 0, SQLState: null]
[2005-03-06 17:26:20,858] [ERROR] (org.hibernate.util.JDBCExceptionReporter.java:58) - [ResultSet is closed]
Name and version of the database you are using:
Access 2003 (custom dialect)
The generated SQL (show_sql=true):
Hibernate: insert into ...this is fine...
Hibernate: select @@identity;
|