I upgraded my project with the latest spring and hibernate releases (spring 3.2.1 and hibernate 4.1.9) but they seem to be incompatible. One of the changes are part of spring's jdbc framework.
public <T> T execute(StatementCallback<T> action) throws DataAccessException {
Assert.notNull(action, "Callback object must not be null");
Connection con = DataSourceUtils.getConnection(getDataSource());
Statement stmt = null;
try {
Connection conToUse = con;
if (this.nativeJdbcExtractor != null &&
this.nativeJdbcExtractor.isNativeConnectionNecessaryForNativeStatements()) {
conToUse = this.nativeJdbcExtractor.getNativeConnection(con);
}
stmt = conToUse.createStatement();
applyStatementSettings(stmt);
Statement stmtToUse = stmt;
if (this.nativeJdbcExtractor != null) {
stmtToUse = this.nativeJdbcExtractor.getNativeStatement(stmt);
}
T result = action.doInStatement(stmtToUse);
handleWarnings(stmt);
return result;
}
catch (SQLException ex) {
// Release Connection early, to avoid potential connection pool deadlock
// in the case when the exception translator hasn't been initialized yet.
JdbcUtils.closeStatement(stmt);
stmt = null;
DataSourceUtils.releaseConnection(con, getDataSource());
con = null;
throw getExceptionTranslator().translate("StatementCallback", getSql(action), ex);
}
finally {
JdbcUtils.closeStatement(stmt);
DataSourceUtils.releaseConnection(con, getDataSource());
}
Hibernate 4.1.9 now proxies jdbc statements and the exception converter now kicks in which throws a runtime exception instead of a checked one. For e.g. Instead of SQLException now a runtime exception is thrown - SQLGrammerException.
Spring probably should be handling this hibernate change, right?
Edit
I discussed on hibernate forums, hibernate jira forums & on the dev mailing list. They claim that since this is a major release (4.x) such compatibility issues are expected. They ask the clients to update their code to resolve the issue.
I have posted the same issue on the spring jira forum and currently its under discussion.
I wonder how others are working around this problem!
Spring agrees to add a patch for this. Probably in 4.x. One of the workaround mentioned right now is
For the time being, a good solution might be to define a PersistenceExceptionTranslationPostProcessor and to mark your JDBC-accessing classes with the @Repository annotation. This will autodetect your Hibernate LocalSessionFactoryBean and use it to translate exceptions based on the Hibernate exception hierarchy, as thrown from JDBC calls in your case. That very same post-processor is also applicable to Hibernate API usage (i.e. sessionFactory.getCurrentSession() usage in your Hibernate-accessing classes)
I have not tried this out since it might not be practical in our case to mark all the jdbc accessing classes with @Repository annotation.