Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JdbcTemplate compatibility with Hibernate 4.1.9's proxied JDBC Statements [SPR-10267] #14901

Closed
spring-projects-issues opened this issue Feb 6, 2013 · 10 comments
Assignees
Labels
in: data status: declined type: enhancement

Comments

@spring-projects-issues
Copy link
Collaborator

@spring-projects-issues spring-projects-issues commented Feb 6, 2013

Amit opened SPR-10267 and commented

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.

We use a combination of JPA (HibernateJPADialect & JpaTransactionManager) & JDBC in our application. For mapped entities JPA is used (included JPQL queries) while for non mapped objects direct JDBC is used.

Spring binds the data source resource with the connection handle created through hibernate jpa dialect. This means any request to create a connection gets delegated to hibernate which proxies connections and statements. Hence when a connection is requested for executing a query through spring's jdbc template we get a proxied connection.

Hibernate 4.1.9 proxies jdbc statements (which was not done in the earlier versions at least 3.6). The proxy throws runtime exception instead of checked exception (SQLGrammerException instead of SQLException is thrown for e.g. in scenarios where a select query is executed on a table which does not exists). Since a runtime exception is thrown, the code in the catch block of jdbc.executeQuery() never gets executed.


Affects: 3.2.1

Reference URL: http://forum.springsource.org/showthread.php?134595-Spring-Compatibility-with-Hibernate-4-1-9&p=437518

0 votes, 5 watchers

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Feb 7, 2013

Juergen Hoeller commented

That catch block in JdbcTemplate is just there to translate SQLExceptions into Spring's DataAccessException hierarchy. Since Hibernate seems to be throwing a non-SQLException there, we can't translate it anyway since the entire SQLExceptionTranslator mechanism is strictly based on actual JDBC SQLExceptions.

From my perspective, proxied JDBC Statements should be throwing proper SQLExceptions. If Hibernate chooses to bypass the signatures there and throw RuntimeExceptions instead, then well, Spring's SQLException translation simply doesn't kick in. JdbcTemplate is still clearing all resources in the finally block.

Juergen

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Feb 7, 2013

Amit commented

So you are hinting that hibernate should have been backward compatible and they should change to throw SQLException's as they did earlier?

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Feb 7, 2013

Juergen Hoeller commented

Well, yes - but my point is also that the only negative behavior is a lack of exception translation. Or are you seeing any kind of resource leak?

Juergen

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Feb 11, 2013

Amit commented

No. There isn't a resource leak. The finally block closes the resources.

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Feb 16, 2013

Amit commented

I discussed this issue on the hibernate dev forum. They mention that since this was an major release (4.x), such changes (i.e. throwing a unchecked exception instead of a checked one in our case) are expected and the client code (in this case - spring) should be modified to resolve the issue.

Kindly let me know your thoughts

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Feb 25, 2013

Juergen Hoeller commented

We might be able to generically check for unchecked exceptions that have a SQLException root cause, invoking our SQLExceptionTranslator that way.

However, I do believe that Hibernate is breaking the JDBC API contract by throwing unchecked exceptions there. JDBC is clearly designed to always throw SQLExceptions, and a JDBC proxying mechanism is supposed to comply with that rule since otherwise, the use of such a proxying mechanism isn't transparent to client code anymore.

Juergen

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Feb 25, 2013

Amit commented

I agree. The proxying mechanism is not transparent. It's hard to convince the hibernate team :). Hope to see the spring fix soon!

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Mar 13, 2013

Juergen Hoeller commented

The changes required to JdbcTemplate and other places where we're calling into JDBC API are somewhat involved and therefore not really a candidate for the 3.2.x line. We'll reconsider for 4.0.x.

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), so maybe it makes sense in any case?

Juergen

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Feb 1, 2014

Amit commented

Any plans to fix this issue? I just came across the migration guide for spring 4.

"The org.springframework.orm.hibernate3 package will be deprecated as of Spring Framework 4.1. We keep fully supporting it for the time being against Spring Framework 4.0. However, we recommend a timely upgrade to Hibernate 4.2/4.3"

To upgrade to hibernate 4.x, we would need this issue to be fixed. Can you please prioritize this?

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Feb 3, 2014

Juergen Hoeller commented

This seems to be fixed in Hibernate itself as of 4.2: https://hibernate.atlassian.net/browse/HHH-7902

As far as we can tell from the current Hibernate 4.2 implementation of the connection() method, we properly get the native Connection back there.

Please try Hibernate 4.2.8 and let me know whether any problems remain...

Juergen

@spring-projects-issues spring-projects-issues added status: declined in: data type: enhancement labels Jan 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: data status: declined type: enhancement
Projects
None yet
Development

No branches or pull requests

2 participants