Correct practice regarding reuse of connection sources in server applications

128 views
Skip to first unread message

Daniel Melo

unread,
Apr 23, 2015, 4:33:28 PM4/23/15
to ormlit...@googlegroups.com
Hi,

First of all I'd like to congratulate about the project which is exactly what I have always looked for: A simple and truly lightweight ORM for Java.

My question is related to the appropriate pattern of reuse (or maybe not reuse?) of connection sources for server applications.


1 - In a server Java application should I create only one JdbcPooledConnectionSource instance and use it all over the application?
2 - If I use this one and only instance of JdbcPooledConnectionSource, should I call the close method after any database access?  Or should I only call close upon the server application shutdown?

Using ormlite-jdbc 4.48 I implemented the approach of reusing a unique JdbcPooledConnectionSource and calling close after each database access. The rationale was to release the connection to be pool as soon as possible. However, using this approach the application fails with a null pointer exception at JdbcPooledConnectionSource, line 122. (conFreeList is null).

My code below. First a utility class that keeps a connection source as instance variable and reuses it for every data access. Note that close is called upon every database access (I'm not sure this is the correct approach)

public class DatabasePersister {
   
   
private static final String DATABASE_CONNECTION_STRING = "jdbc:h2:mem:ormlite-sandbox";
   
   
private ConnectionSource connectionSource;
   
   
public DatabasePersister() {
       
try {
            connectionSource
= new JdbcPooledConnectionSource(DATABASE_CONNECTION_STRING);
           
TableUtils.createTableIfNotExists(connectionSource, Entity.class);
           
       
} catch (SQLException e) {
           
throw new RuntimeException("Failed to create connection source", e);
       
}
   
}
   
   
public List<Entity> readData() throws SQLException {
       
try {
           
Dao<Entity, Long> dao = DaoManager.createDao(this.connectionSource, Entity.class);
           
return dao.queryForAll();
       
} finally {
           
this.connectionSource.close();
       
}
   
}
   
   
public void saveData(final Entity entity) throws SQLException {
       
       
final Dao<Entity, Long> dao = DaoManager.createDao(this.connectionSource, Entity.class);
       
       
TransactionManager.callInTransaction(this.connectionSource, new Callable<Void>() {
           
@Override
           
public Void call() throws Exception {
                dao
.create(entity);
               
return null;
           
}
       
});
       
   
}

}

The application code do some data acess:

public class App
{
   
public static void main( String[] args ) throws Exception
   
{
       
DatabasePersister persister = new DatabasePersister();
        persister
.readData();
        persister
.saveData(new Entity(1L, "some data"));
       
       
System.out.println("Program terminated successfully");
       
   
}
}

This code fails within saveData method execution when JdbcPooledConnectionSource.getReadWriteConnection tries to check the size of connFreeList (private variable of JdbcPooledConnectionSource) and it is null. The close call within previous database access has set it to null.

In this sample I have two assumptions which I am not sure they are correct:

a - I am creating DAO instances upon every database access. For that I am relying on the DaoManager cache that was mentioned in this group in other message.
b - When TransactionManager is used I don't call close on connection source. I assume TransactionManager will release the resources upon termination

Can someone confirm these assumptions?

I am also attaching the sample application. The sample application mimicks a Java server application.

Am I missing something here? Based on the manual it was not clear to me what the correct approach. Maybe my mindset is too much tied to JPA's entity manager and I am applying an incorrect pattern.

Thanks very much,

Daniel


ormlite-sandbox.tar.gz
Reply all
Reply to author
Forward
0 new messages