Issue Details (XML | Word | Printable)

Key: HHH-2603
Type: Deprecation Deprecation
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Steve Ebersole
Reporter: Steve Ebersole
Votes: 0
Watchers: 7
Operations

If you were logged in you would be able to see more operations.
Hibernate Core

Deprecate the Session.connection() method

Created: 08/May/07 08:55 PM   Updated: 19/Dec/08 12:31 PM
Component/s: core
Affects Version/s: None
Fix Version/s: 3.2.4

Time Tracking:
Not Specified

Issue Links:
Fix
 
Relates
 


 Description  « Hide
Deprecate the Session.connection() method, in favor of a "JDBC work" API. Schedule for removal in 4.0

 All   Comments   Work Log   Change History   FishEye      Sort Order: Ascending order - Click to sort in descending order
Steve Ebersole added a comment - 08/May/07 09:00 PM
trunk / 3.2

John Aylward added a comment - 02/Jul/07 11:04 PM
Could you add in some documentation for what we could use instead of connection()? If the option to not use hibernate to grab an unmanaged connection is the correct way, it should be documented in the deprecation notes.

The API docs need to be updated on documents section of the hibernate.org website to reflect the deprecated methods

Martin Rose added a comment - 02/Aug/07 12:32 PM
Agreed, I've been searching for a 1/2 hour through JIRA, the wiki, and the source in FishEye and it is not at all apparent what the *recommended* way is to retrieve the active connection for a session.

Glen K. Peterson added a comment - 05/Aug/07 07:41 AM
Did you deprecate the method before providing an alternative or is there an alternative you just aren't telling people about? Since I require "no errors, no warnings" in all my compiles, it distresses me that after downloading Hibernate Core 3.2.5.ga, I now have 3 warnings over this deprecated method. I guess I'll have to switch back to an older version until this is fixed with documentation or by undoing the deprecation warning.

Steve Ebersole added a comment - 05/Aug/07 11:10 AM
Did you think before making this comment or is there some intelligence here you are just not telling people about :)

Glen K. Peterson added a comment - 05/Aug/07 01:32 PM
That's the nicest thing anyone's said to me all day!

When the @deprecated tag is used in JavaDocs, there is usually a comment that suggests a working alternative. This deprecation warning is unusual because the accompanying comment suggests an alternative that does not seem to exist yet. What am I missing?

Steve Ebersole added a comment - 05/Aug/07 02:26 PM
Its the same basic tone as your moaning couched in a rhetorical question.

Did you read the deprecation? > "To be replaced with a SPI for performing work against the connection;...". Now granted I was an English Lit major in college, so perhaps that comes into play and I take things for granted, but "to be" is clearly future imperfect tense. Future imperfect tense indicates something yet to be done.

Mark Reynolds added a comment - 22/Aug/07 05:52 PM
Deprecation is for cases where an alternate API has been provided and use of the old one is now discouraged and/or planned for removal. It is unusual and confusing to deprecate a method for which there is no current alternative.

If you prefer to disparage those who are thusly confused rather than simply remove the premature deprecation, so be it.

Max Rydahl Andersen added a comment - 23/Aug/07 01:31 AM
Deprecation does not necessarily means there are an alternate API - just look at the deprecation of System.getEnv() in jdk 1.2 to jdk 1.4. There were no alternative to get system variables, but it was still deprecated.

Please let us know what other means we have to make sure that everyone becomes aware of the dangers of using .connection() and that they should know that it will be removed/changed later on to ensure proper handling of resources.


Glen K. Peterson added a comment - 23/Aug/07 12:01 PM
I recommend that you list the dangers of using Session.connection() in the JavaDocs for that method and update any other documentation accordingly. The JavaDocs are the first place I would look for that type of information and it's also where I would most likely find it by accident.

I still think it's premature to mark it deprecated. Deprecating a method means that "you should no longer use it, since it has been superseded and may cease to exist in the future."
Source:
http://java.sun.com/j2se/1.5.0/docs/guide/javadoc/deprecation/deprecation.html

Steve Ebersole added a comment - 23/Aug/07 08:33 PM
ummmm... ? Yeah.... what?!?!

This "discussion" is done.

Landon Fuller added a comment - 23/Sep/07 02:03 PM
Was the result of this discussion that:
    - Developers should assume that in a future release, it will not be possible to retrieve a JDBC Connection object at all?
or
    - An API to retrieve the connection will be available in some other form?

The current JavaDoc notice is unclear on that point.

If there will be an alternative API to access a JDBC Connection, then I'm inclined to attach a comment and @SupressWarnings attribute to my single use of connection(), and replace the usage when the build breaks.

If the API is going away entirely, and access to an underlying JDBC connection will not be available, then I need to write an alternative implementation.

Steve Ebersole added a comment - 25/Sep/07 09:00 AM
The first thing you need to realize is that there are 2 reasons people use Session.getConnection():
1) do JDBC work
2) create "temporary sessions"

The alternative/replacement will be different for each.

As for #1, there will be a method to "perform some work", where work is an interface representing some functionality that needs concise access to the JDBC connection

#2 is still being discussed as to the best approach. The likely approach is consolidation of the openSession methods to take an encapsulation of "creation options".

Hontvári József added a comment - 26/Oct/07 08:46 AM
Yes, deprecation doesn't mean that there is an alternative API, but that is not a problem here. There are two kind of deprecation:
1) something was wrong and cannot be fixed therefore no alternative method is provided. Like Thread.stop. In the deprecation comment Sun provides a very detailed problem description so you can understand the consequences and risks of the (continued) usage of the method.
2) something is wrong or not optimal and it WAS replaced by something better. Like getenv, Sun recommended the system properties in the deprecation comment.

I believe in this case the deprecation was either used for an inapproprate purpose (roadmap?) and/or the deprecation comment is missing.

I really appreciate Hibernate developers, but I think in this case you don't understand that during maintenance deprecated class/method usage requires attention, it may indicate real problems and it means tasks to do, and you treated this problem a bit too lightly.

M Stewart added a comment - 29/Oct/07 11:21 AM
How is this for an alternative (assuming you have access to a Configuration object):

Connection conn = configuration.buildSettings().getConnectionProvider().getConnection();

This seems to provide the behavior that I was looking for, namely access to a JDBC connection connected to the same database. No need for it to be related to a session. Does this violate some aspect of the Hibernate design?

Justin Levis added a comment - 14/Feb/08 07:03 PM
I need to get access to the current connection so I can display the connection URL in my application. That's it, simple. That doesn't exactly sound like "do JDBC work", but I am after JDBC information. In this case, I'm just using it as a visual confirmation that the users are running the correct application and it's connecting to the correct database, etc.






Steve Ebersole added a comment - 15/Feb/08 04:40 AM
Getting a connection directly from the ConnectionProvider is a different scenario, and is fine. There you are getting a connection for your own use. Even in the case of JTA, you may get the same logical connection as what is being used by a Session; however, you would get a different physical connection handle.

We are specifically talking about the scope/duration of connections in relation to a Session.

And you can get the ConnectionProvider from the SessionFactory as well. You just need to cast it to org.hibernate.engine.SessionFactoryImplementor, and call org.hibernate.engine.SessionFactoryImplementor#getConnectionProvider. org.hibernate.engine.SessionFactoryImplementor is not a public API; it is however an integration API and as such is pretty stable.

Glen K. Peterson added a comment - 19/Mar/08 09:52 AM
Thank you very much, Steve. This is just what I needed. I apologize for my haughty tone earlier.

For the record, I also tried an earlier suggestion:
hibernateConfig.buildSettings().getConnectionProvider().getConnection();

and got:
FATAL org.hibernate.connection.ProxoolConnectionProvider::configure(150): Proxool Provider unable to load load Property configurator file: proxool.properties
org.logicalcobwebs.proxool.ProxoolException: Attempt to register duplicate pool called 'pool1'

So Steve's suggestion appears to be the best solution.

Dilip Dalton added a comment - 18/Dec/08 03:41 PM
Removing this method without an alternative to getting a JDBC connection will prevent us from upgrading to 4.0.

The product we work is a huge enterprise level J2EE software with more than a million lines of java code. The code has been developed on for more than a decade and we have different persistent mechanisms (JDBC, direct hibernate, Spring with hibernate) that need to work together. The common transaction semantics is achieved by passing the JDBC connection from the hibernate session to the legacy part of the code that needs to work with JDBC.

It is not possible to rewrite all the code using hibernate. So please let us know if an alternative method to get the JDBC connection from hibernate session will be provided.

Steve Ebersole added a comment - 19/Dec/08 09:30 AM
Dilip, currently you do something akin to:

doSomeLegacyJunk( session.getConnection() );

why on God's green earth does everyone think it is so inconceivable to instead do:

session.doWork(
    new Work() {
        public void execute(Connection connection) throws SQLException {
            doSomeLegacyJunk( connection );
        }
    }
);

???

Shawn Clowater added a comment - 19/Dec/08 10:39 AM
Steve, while the work API is fantastic and works for 90% of our cases we are still using the .connection() method in order to open up a secondary session in order to do stuff like our audit logging. I don't care about using the raw connection really it is more about being able to have a 'child' session. There is already somewhat an API in place for that but you can't actually get 2 sessions of the same entity mode due to this.


Off the SessionImpl
public Session getSession(EntityMode entityMode) {
if ( this.entityMode == entityMode ) {
return this;
}




Steve Ebersole added a comment - 19/Dec/08 10:49 AM
Shawn, I am responding specifically to the questions that keep cropping up on this specific issue which invariable seem to discuss exactly this type of usage.

Its been discussed (and I thought you were involved in some of them) that yes there still needs to be an API for obtaining a 'child session' (specifically one utilizing the same JDBC connection). This will happen before 4.0. The rub, to me, is the already large number of overloaded SF.openSession() methods we have; that needs to be considered carefully. But honestly I have not had time to think through the details of it; feel free to put some thought into it and start a discussion on the dev list. (BTW Session.getSession(EntityMode) has a totally different purpose/intent)

Paul Benedict added a comment - 19/Dec/08 11:52 AM
What about moving the connection() method to the "classic" package? Maybe a Session3 interface would help the migration.

Dilip Dalton added a comment - 19/Dec/08 12:31 PM
Steve, thanks for describing the work API.

We can use this work API, but it will involve a bigger refactoring work compared to obtaining the JDBC connection object. Given how stable and mature the code has been, it is highly likely that we will never do this refactoring on the legacy code.