my dog learned polymorphism*
The moose likes Object Relational Mapping and the fly likes How to detect wrong login earlier Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


JavaRanch » Java Forums » Databases » Object Relational Mapping
Bookmark "How to detect wrong login earlier" Watch "How to detect wrong login earlier" New topic
Author

How to detect wrong login earlier

Werner Joerling
Ranch Hand

Joined: Mar 23, 2003
Posts: 35
Hello,

in my hibernate.cfg.xml file I leave the properties "hibernate.connection.username" and "hibernate.connection.password" empty.
My application (a gui dialog) asks the user at startup time for the login data. (For your interest: I'm using the c3p0 connection pool.)
In case of a correct login all works fine.
In case of a wrong login the application resumes as usual, but comes after a long time with the java.sql.SQLException: "Connections could not be acquired from the underlying database!" caused by
com.mchange.v2.resourcepool.CannotAcquireResourceException: "A ResourcePool could not acquire a resource from its primary factory or source."

My question: How can I detect the wrong login earlier?
I can't explain the users why they should wait as long for the error message.
They want to have an immediate message like "Wrong password/username".

Ho can I realize this behavior?

Regards

Werner
Balaji Loganathan
author and deputy
Bartender

Joined: Jul 13, 2001
Posts: 3150
It is a not good way to use the user entered credentials for connecting to database directly. Of course you will get an error message after a long time bcos the class to get a connection to db.


Spritle Software Blogs
Paul Sturrock
Bartender

Joined: Apr 14, 2004
Posts: 10336

One way would be to validate the login credentials when you get them (I'm not 100% sure why you wouldn't do this anyway - if you don't do this, why get them at all?). All you need to do is try to directly create a Connection with these credentials and catch the SQLException if one is thrown. You could parse the Exception to make sure it is a permissions exception, but since any SQLException when you create a connection amounts to the same thing (i.e. you can't connect) I'm not sure this matters.


JavaRanch FAQ HowToAskQuestionsOnJavaRanch
Werner Joerling
Ranch Hand

Joined: Mar 23, 2003
Posts: 35
Originally posted by Balaji Loganathan:
It is a not good way to use the user entered credentials for connecting to database directly. Of course you will get an error message after a long time bcos the class to get a connection to db.


Thank you Balaja,

can you explain me why this is not a good way?

Regards

Werner
Werner Joerling
Ranch Hand

Joined: Mar 23, 2003
Posts: 35

Originally posted by Paul Sturrock:

One way would be to validate the login credentials when you get them (I'm not 100% sure why you wouldn't do this anyway - if you don't do this, why get them at all?). All you need to do is try to directly create a Connection with these credentials and catch the SQLException if one is thrown. You could parse the Exception to make sure it is a permissions exception, but since any SQLException when you create a connection amounts to the same thing (i.e. you can't connect) I'm not sure this matters.


The credentials are needed to authenticate and authorize the user against the database. Hibernate or more precisely the connection pool needs them to get the connections. That's the reason for getting the credentials. Furthermore the credentials are user-specific. I do not want to publish shared login data in a common readable configuration file.

Because the connection pool will try to connect the database, I think it must be able to detect failing login data and to come up with an appropriate message (therefore we have the SQL return codes), instead of retrying to connect over and over again and at last to come up with an unspecified connection error.

Why should I get an useless JDBC connection only to verify the credentials? It's hibernate's and the connection pool's task.

The most database tools I know, come up with an error message in case of failing login data. Why can I not do so?

Thanks for the answer.

Regards

Werner
Paul Sturrock
Bartender

Joined: Apr 14, 2004
Posts: 10336


Why should I get an useless JDBC connection only to verify the credentials?

I'm not sure its useless - if you want to verify you can connect to a database with the credentials supplied by the user the only way you are going to be able to do it is by trying to connect to the database and acting accordingly if you can't. Now you can do that by trying to create a connection explicitly and catching the SQLException, or you can wait till Hibernate tries to connect and act then.


It's hibernate's and the connection pool's task.

No. Strictly is the DataSource's task. Both Hibernate and the connection pool trust the DataSource is valid.


The most database tools I know, come up with an error message in case of failing login data. Why can I not do so?

...and they usually do this by trying to connect to the database and reporting the error if the connection fails. If you do the same you can replicate this behaviour.


Because the connection pool will try to connect the database, I think it must be able to detect failing login data and to come up with an appropriate message (therefore we have the SQL return codes), instead of retrying to connect over and over again and at last to come up with an unspecified connection error.

Normally SQLExceptions just return the error message generated by the database. If your are getting something other than a "login denied" or "unknown user" type exception, my guess is the SQLException might be being changed by the connection pool. Now considering the applciation you have described it sounds like a stand alone desktop application. If it is, why are you using a connection pool? You only need a maximum of one connections.
Werner Joerling
Ranch Hand

Joined: Mar 23, 2003
Posts: 35
Hello Paul,

so far I understand.
Your tips help me a lot. Thanks.



Now considering the applciation you have described it sounds like a stand alone desktop application. If it is, why are you using a connection pool? You only need a maximum of one connections.



You are right.
I'm using a connection pool because Hibernate does it by default.
It uses a built-in connection pool. But in the the documentation the
built-in conn pool is not recommended for production use. It has the disadvantage, that the connections are not kept alive and exceptions are thrown after timeout. (I do not know how to reconnect).
Therefore I'm using the c3p0 conn pool. (It's the first one in the list of recommended conn pools). This conn pool keeps the connections alive. (One can see this in the log). I configured min-size and max-size of the conn pool as 1.

<property name="c3p0.min_size">1</property>
<property name="c3p0.max_size">1</property>

I do not know, how to use hibernate without a conn pool.
And I do not know how to solve the timeout problem myself. (My only idea is to send periodically a query, which has to be as cheap as possible).

Regards

Werner
[ December 12, 2006: Message edited by: Werner Joerling ]
Paul Sturrock
Bartender

Joined: Apr 14, 2004
Posts: 10336

Ah yes, I'd fogotten about that (I tend to work with a container, so always defer to the DataSource for any Conection Pool implementaion).

Just so you know, to avoid using a pool, you need to implement your own ConnectionProvider and configuring Hiobernate to use it via the hibernate.connection.provider_class property.
Mr. C Lamont Gilbert
Ranch Hand

Joined: Oct 05, 2001
Posts: 1170

I had a similar problem. I found that Hibernate will swallow the exception when I create the Session Factory. And Hibernate will wait until the session is created and used to throw a real exception. Much later than I desire.

I use JDBC to not just validate the user credentials, but also to see if the database schema is present before I do a table drop and create. So I can tell the user he is about to dump data.
 
GeeCON Prague 2014
 
subject: How to detect wrong login earlier