I'm confused about the difference between DataSource and SessionFactory.
I think SessionFactory is a manager for retrieve Sessions (which are in fact connections to a database I guess).
DataSource has the method getConnection()
"Attempts to establish a connection with the data source that this DataSource object represents."
It means a DataSource object always works directly with the database?
If I have a pool of connections, DataSource will ask to the pool for a connection? Or will it try to get another connection to the database.
Are in fact DataSource and SessionFactory the same? Both try to give sessions/connections?
Datasource maintains the pool of connections, establishes the connection, knows how to connect etc.,
User configures data source either in the server(like websphere/weblogic) or in the spring/hibernate configuration file. Either way you give the handle of this data source to the sessionfactory during the app startup.
SessionFActory is an interface which hides all the details like opening the connection / closing the connections. Through out your development time you dont worry about these small things like loading driver/closing connection/opening etc., so you can concentrate on business logic/other important stuff.
Related
I have a doubt of how the spring boot JDBC template works. I have read the documentation , but could not understand clearly :( When does the template opens connection , when does it gets closed . How does the transactions are handled . Does it gets opened and closed for every query execution ?
When does the template opens connection, when does it gets closed
For building JdbcTemplate you should specify the JDBC DataSource to obtain connections from:
public JdbcTemplate(DataSource dataSource)
Or:
public JdbcTemplate()
JdbcAccessor.setDataSource(javax.sql.DataSource)
Conclusively, JdbcTemplate works with this DataSource.
DataSource, depending on the implementation, may return new standard Connection objects that are not pooled or Connection objects that participate in connection pooling which can be an be recycled.
JdbcTemplate has pooled connections and releases them back to DataSource.
How does the transactions are handled
JdbcTemplate relies on database transactions.
If you want to operate transactions on service layer/business logic you need transaction management.
The simplest way is to annotate services with #Transactional or use org.springframework.transaction.support.TransactionTemplate.
I have assigned hibernate session to instance variable of an immutable class. The class uses this session object (instance variable) to create hibernate query. The code works fine.
Due to this is it possible that the connection pool does not have free connections to database.
Session will take a single connection from the connection pool. Other connections will be free. Please refer the Hibernate manual,
*It is advisable to have the org.hibernate.SessionFactory create and pool JDBC connections for you. If you take this approach, opening a org.hibernate.
Session is as simple as:
Session session = sessions.openSession(); // open a new Session
Once you start a task that requires access to the database, a JDBC connection will be obtained from the pool.*
I have a basic question about the Tomcat 7 JDBC Connection Pool: is a separate pool created for each separate database (i.e., URL)? Or is a single pool created that holds open connections from any number of different databases?
For example, if I open connections to databases A and B by doing this:
PoolProperties poolProperties = new PoolProperties();
poolProperties.setDriverClassName("org.postgresql.Driver");
poolProperties.setUrl("jdbc:postgresql://myserver/db_a");
poolProperties.setInitialSize(1);
poolProperties.setMaxActive(10);
poolProperties.setMaxIdle(1);
poolProperties.setMinIdle(0);
and then this:
PoolProperties poolProperties = new PoolProperties();
poolProperties.setDriverClassName("org.postgresql.Driver");
poolProperties.setUrl("jdbc:postgresql://myserver/db_b");
poolProperties.setInitialSize(1);
poolProperties.setMaxActive(10);
poolProperties.setMaxIdle(1);
poolProperties.setMinIdle(0);
Have I just created one pool with a maxActive of 10, or two pools, each with a maxActive of 10? If it's one pool, what if I had changed maxActive to, say, 30 when opening the connection for database B? Does the first call to setMaxActive win, or does the second call override, or does this cause a separate pool to be created?
Okay, I did some digging and figured this out myself. (Thanks for the many kind folks on the tomcat-users mailing list!)
JB Nizet is right: if you are creating Tomcat database connection pools from Java code, each DataSource you instantiate literally is/represents a separate connection pool. This was surprising to me; coming from a .NET background, I assumed the Tomcat connection pooling would work like SqlServer/ADO.NET connection pooling: if you use two identical connection strings to get two database connections, these will both come from the same connection pool. However, in Tomcat, when instantiating DataSource objects from Java code, each new DataSource instance is a whole new connection pool. So, if you want to persist these connection pools across JAX-RS web service calls, for example, you need to build your own database-pool (DataSource) cache, put the DataSource instances (one per database) into it, and store it in an object that JAX-RS will persist across web service calls. I just did this, and it is working fine.
btw, Tomcat database connection pooling does offer functionality similar to SqlServer/ADO.NET connection pooling, you just have to use JNDI resources to create your DataSource instances. (In my case this is not an option, since databases are created dynamically in my application, and JNDI definitions are generally created from config files that Tomcat reads at startup.)
What is the difference between javax.sql.DataSource and javax.sql.ConnectionPoolDataSource? I don't know which resource type to use when I am creating a connection pool in GlassFish for MySQL.
ConnectionPoolDataSource is just a DataSource (as it inherit's CommonDataSource which is also inherited by DataSource) with capability of Connection Pooling -
you asked : I don't know which resource type to use
It depend's on your application, many database drivers take a long time to create a new connection with database, If your application is going to create too many connection's (very frequently). use connection pooling.
I'm using GWT with Hibernate, c3p0 and MySQL to produce a web app with a limited audience (max 50 users per day). During testing I found that Hibernate was opening a connection with each session but not closing it, irrespective of use of the close() method.
My current configuration is as follows:
hibernate.connection.driver_class=com.mysql.jdbc.Driver
hibernate.connection.url=
hibernate.connection.username=
hibernate.connection.password=
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.current_session_context_class=thread
hibernate.c3p0.min_size=1
hibernate.c3p0.max_size=1
hibernate.c3p0.timeout=10
hibernate.c3p0.max_statements=50
hibernate.c3p0.idle_test_period=10
hibernate.c3p0.unreturned_connection_timeout=1
hibernate.connection.provider_class=org.hibernate.connection.C3P0ConnectionProvider
With each new connection to the application a new pool is created. For example if I set the pool size to 3, 2 connections to the application result in 6 connections until the application is closed.
The intended behaviour is to simply close or reuse the connections after each transaction. How can I achieve this?
During testing I found that Hibernate was opening a connection with each session but not closing it, irrespective of use of the close() method
When using a connection pool, calling Connection#close() doesn't physically close the connection but return it to the pool for future reuse. In other words, the connection stays open and that's the whole point of using a pool.
I call the following: AnnotationConfiguration().buildSessionFactory().getCurrentSession();
Well, that's the problem. You are creating a SessionFactory over and over (each creating its own pool) while you should create it only once for the lifetime of your application. If you are not using any particular framework, this is typically done in some utility class (the famous HibernateUtil class).
The official Hibernate Tutorial has a very basic example of such a class. Or see this one which is a bit richer.
The concept of a connection pool is exactly that. You have a pool of opened connnections, and when you need to do a transaction, you get a connection already opened. This way, you save a lot of time opening and closing connections. But you pay the price to keep the connections opened when you are not using them.
You have more info about c3p0 configuration
Update Apparently the OP was calling buildSessionFactory once per session. This has to be called once per lifetime of the application.
Here's the utility class that builds the sessionFactory of Hibernate and provides the session class to whoever asks for it. This is the cumberstone for a DAO class.
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.classic.Session;
public class HibernateUtil {
private static final SessionFactory sessionFactory;
static {
try {
// Create the SessionFactory from hibernate.cfg.xml
sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
} catch (Throwable ex) {
// Make sure you log the exception, as it might be swallowed
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
public static Session getCurrentSession() {
return sessionFactory.getCurrentSession();
}
}
Its not a good ideia to use a Connection Pool if you want to close the connection after each transaction. It's exacly what connection pools want to avoid... You should just turn off C3PO. Hibernate will handle the connection by himself (open and close as simple JDBC connection in each transaction)