I'm doing some work on a JSP site that was coded very badly. For every single database call the original programmer opens and closes a database connection. I'm adding in some new database operations and I would like to do things a little bit better( something like hibernate will come later when more of the site can be rebuilt ). I was thinking of creating a single database connection when a session starts ( after logging in ), storing it in the session object and then closing it in session listener end of session handling function when the session closes. Is this a sound strategy? Thoughts?
I was thinking of creating a single database connection when a session starts ( after logging in ), storing it in the session object and then closing it in session listener end of session handling function when the session closes. Is this a sound strategy? Thoughts?
No. Create a container managed connection pooled data source and get it by JNDI on webapp's startup.
How to create the data source depends on the container in question. In case of for example Tomcat 6.0, you can read it up here: Tomcat JNDI Resources HOW-TO - JDBC Data Sources. In case of for example Glassfish 3, you can do it in the webbased admin console on http://localhost:4848.
Here's how you can finally get it from JNDI:
DataSource dataSource = (DataSource) new InitialContext().lookup(jndiName);
// ...
You can call getConnection() on it. It's sufficient to get the data source only once during webapp's startup, for example in a static initializer block of your database connection manager or perhaps in a ServletContextListener.
The connection should always be acquired and closed in the shortest possible scope. Get it inside the try block where you're executing the query and close it in the finally of the very same try block. Do not keep the connection open longer than necessary. The connection pool will take care about keeping them open, so the performance is already greatly improved that way.
Without commenting on your idea (because I've never done it that way so I don't know for sure), I can say that I've always seen it done something like this (see accepted answer):
How to reuse the same connection with a Spring's JdbcTemplate?
For starters you use a Common DBCP's PoolingDataSource instance stored in your ServletContext (or "application scope" in JSP parlance).
Ideally I would look to migrating to Spring (or Guice or similar).
Related
I have a scenario where I need to configure the Mongo DB in Java Application. I don't use Spring, but I need to make the connection to DB as common so that whenever there is a transaction that is going to happen, it must create a connection automatically and it must close the connection when the transaction is done.
EDIT:
How to make the connection common instead of creating the instance each time when the transactions are done?
You can see an example of transactions working with Java code (and without Spring):
Article: https://www.mongodb.com/blog/post/java-and-mongodb-40-support-for-multidocument-acid-transactions
GitHub: https://github.com/MaBeuLux88/mongodb-4.0-demos
I have used MySqlDataSource for in jdbc connectivity.I have used following code
MysqlDataSource d = new MysqlDataSource();
d.setUser("user");
d.setPassword("pass");
d.setServerName("hostname.com");
d.setDatabaseName("db");
Connection c = d.getConnection();
Also i have searched there is an option of Configuring a MySQL Datasource in Apache Tomcat.
Is there any performance difference between these two? which one is best to use?
Configuring Datasource in tomcat will help you to share same data source between applications running in same tomcat. that Datasource will be managed by container (tomcat in your case).
while the Datasource created in code will be created by your application and can be used by that application only.
So if you have multiple application running on tomcat and accessing same data source, that configuring Datasource in tomcat will be good approach and have performance factor because only one data source is created and not having separate connections for each application
But if you have only single application that the first approach you have used is good one
They both use the internally the same driver, i dont think the performance is much different here, i guess if you need to access teh database only at that place and the enduser isn't supposed to use his own authentication you may use it directly from java, but if you will need the connectivity on different places it could be helpful to configure this using apache configuration, specially that if anything changes like database server, user name or whatever you don't need to get in the code to change it, this could be very important if end users have to set their own configurations.
The improvement of configuring a pool of Connections (as the one provided by tomcat) is mainly that you will actually create and close a lot less of connections.
When using a pool, when you request a Connection to a pool it will look if it has any connection already created and available for reuse and, if it has, it will provide you with it (instead of creating a new Connection, which is a heavy operation). You must still close() a Connection provided by Tomcat so Tomcat knows that it can now reuse when it is requested again.
Additionally, the advantage of the pool is that your code does not need to know the configuration data for the Connection. He just requests a Connection from a given pool and the sysadmin configures it, allowing for greater flexibility (the sysadmin does not need to know how to configure your app, just how to configure the Tomcat which is fairly more standard).
I'm developing a web application with Java and it needs a connection with a data base. Well administration of resources is very important. The application will be in a Tomcat 6 servlet container, and I've implemented BoneCP to manage connections (I can't use Spring).
I've read that JNDI lookup for DataSource is too much expensive and I'm thinking about creating a singleton of DataSource object, to get the JNDI resource only once, and return the same DataSource for future connections.
Question: Is it a good idea to create a DataSource only once, and get connections from the same DataSource? I don't want to get the same connection, only the same DataSource.
Thank you ;)
Use a pooling datasource, such as is described here:
http://www.javaranch.com/journal/200601/JDBCConnectionPooling.html
Yes, as Renjith suggested, you only need to create the DataSource one time. I actually ran into this same issue yesterday. Every time in my "getConnection" method I noticed I was creating a new InitialContext and DataSource unnecessarily. I revised my Connection Manager class to have a static block of code that creates the DataSource object only when the class gets loaded the first time (after reading BalusC's answer in Proper usage of JDBC Connection Pool (Glassfish))
I thought about using the old-school ServiceLocator pattern (see Pascal's answer in the above link), but I felt it was a bit too overkill for my needs.
Another possibility is that you could also use the #Resource annotation with injection on the DataSources, but that doesn't seem to work with Tomcat 7.
I have some code that I want to make public. The code sends email via servers, connects to databases, and other tasks requiring usernames/passwords.
I'd like to store the passwords and such in a seperate configuration file so that I don't have to sanitize my code on every commit.
How can I do this? It would be easy to do in C using #define, but I'm not sure how to accomplish this in Java.
EDIT: The environment I'm using is Glassfish
The basic method is put the information in a properties file and use the Properties class to load it at run time. If you're using a J2EE server, database connections are configured in the server and the code references them by an abstract name.
I think I should add that if you're using a server, how to configure it and how to get the connections to your code will vary by server and J2EE level so post your environment. Using the Properties class is pretty obvious just by looking at the javadoc and the load() methods.
In glassfish, go to the admin console and under Resources create a new connection pool. That defines your database connection and will share a pool of those connections among your applications. Now under JDBC Resources, create a new entry that maps that pool to a name. The name is usually something like jdbc/myappname.
For a J2EE5 or later application, you can now add this as a class level variable:
#Resource(mappedName="jdbc/myappname") DataSource myDS;
At runtime the server will inject that resource to your database pool. Then when you need a connection, you can do this inside any method:
Connection conn = myDS.getConnection();
The result is your code doesn't have to care at all about the database connection information or managing a pool of connections. You can deploy the identical code on development and production servers, and they will get an appropriate connection. In order to get the injection, it has to be a class the server creates like an EJB, servlet, tag library handler, or JSF managed bean.
I have a Tomcat servlet that incorporates hibernate. It works fine normally. When the servlet starts I initialize hibernate and create a session factory. I then use this session factory to generate sessions when performing various database transactions. So far so good. My problem comes after a long period of inactivity on the servlet (say when the users go home for the night and then try to log in the next morning). Suddenly, I am unable to communicate with the databse. In the logs I see
org.hibernate.exception.JDBCConectionException: Could not execute query.
If I stop and restart Tomcat, reinitializing my servlet and rebuilding my session factory, everything works fine. It is almost like the session factory itself is timing out?
Any ideas?
Thanks,
Elliott
If I stop and restart Tomcat, reinitializing my servlet and rebuilding my session factory, everything works fine. It is almost like the session factory itself is timing out?
It's not the session factory but the connections used by the session factory (e.g. MySQL is well known to timeout connections after 8 hours of inactivity by default). Either:
use a connection pool that is able to validate connections on borrow and to renew them ~or~
increase the idle timeout on the database side
OK. Suppose I use a c3P0 connection pool. How do I specify in the hibernate.cfg.xml file that I want to "validate connections on borrow" or does it do this by default?
The various options when using C3P0 are documented in Configuring Connection Testing. My advice would be to use the idleConnectionTestPeriod parameter:
The most reliable time to test
Connections is on check-out. But this
is also the most costly choice from a
client-performance perspective. Most
applications should work quite
reliably using a combination of
idleConnectionTestPeriod and
testConnectionsOnCheckIn. Both the
idle test and the check-in test are
performed asynchronously, which leads
to better performance, both perceived
and actual.
Note that for many applications, high
performance is more important than the
risk of an occasional database
exception. In its default
configuration, c3p0 does no Connection
testing at all. Setting a fairly long
idleConnectionTestPeriod, and not
testing on checkout and check-in at
all is an excellent, high-performance
approach.
To configure C3P0 with Hibernate, be sure to read the relevant instructions (and to use the appropriate properties, and the appropriate files).