Unexpected ResultSet is closed exception at Spring web application
We have a spring bean that loads application messages from a Postgresql (8.4) database at startup. Bean definition is like : <bean .... init-method="loadMessages">
The code is pretty straight forward :
get a connection (we are using a dbcp pool)
Create a statement (plain jdbc, nothing special)
execute the query, get the result set
while(resultSet.next())){
cacheMap.put(resultSet.getString("column1"), resultSet.getString("column2"));
}
The code sometimes throws a ResultSet is closed exception inside the while loop at application startup. It works fine without any exceptions using a Postgresql 8.4.2, but throws exceptions most of the time (not always) when using a Postgresql 8.4.8.
We tested it on 4 different computers开发者_Python百科 running windows 7 or 2008 server, Tomcat 6.0.32, latest versions of java 1.6, all database servers run on the same machine. The resultset contains about 8000 rows (two columns; character varying(200) and character varying(1000)) . What can be wrong here?- Is it possible that the pool is closing the connection, or reusing it, before we are done processing the result set ?
- Or can it be something related to the database versions?
By the way we changed the code to load the messages when they are used for the first time instead of application start up and it is working fine. So this exception is only raised when the code is called at startup, using init-method.
Thanks in advance
My initial thought is that you may be using a Spring container bean before it has been completely initialized. This can sometimes lead to inconsistent behaviour (things may not initialize in the same order when there is a config change or library change). Your last paragraph also indicates dependency initialization issues.
Spring uses the ref wirings to decide which beans should be initialized first. But if your init method accesses container beans (rather than using injected beans), Spring doesn't know about that and you may be accessing a bean that has been constructed but not yet initialized. Caches and static initializers seem to be typical candidates for this kind of grief.
Your solution of moving the cache building activity to a time after the Spring container has been built seems like a good solution to me. If it is a dependency initialization issue and you can guess which bean is not complete (say the connection pool), you can use "depends-on" in your bean config to force the initialization of the other bean first.
If it is an initialization issue, then I would expect that when you get the "result set closed" exception, it is always on the first hit of the while(resultSet.next())) statement and you will have nothing in your cache. Either things are not initialized properly and it fails right away, or things did initialize properly and your cache populates. If the cache is partially populated and the result set error is happening partway through reading the result set, then the entire initialization theory doesn't really make sense any more.
精彩评论