Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

COPY FROM and C3PO connection pool in Postgres

I have the follow code in my JAVA program that allows me to copy data from a file into my Postgres database:

Connection con = DriverManager.getConnection("jdbc:postgresql://localhost:####/myDb", 
                                                   "myuser", "mypassword"); 
CopyManager cm = new CopyManager((BaseConnection) con);
cm.copyIn("COPY prices FROM STDIN WITH DELIMITER AS ','", 
             new BufferedReader(new FileReader(filepath)), buffersize);

This code works fine, but I would like to use a connection pool to manage my connections, as I have this code running for numerous files. So I used C3P0.

public static final ComboPooledDataSource cpds = new ComboPooledDataSource();

public class MyPooledConnection {
MyPooledConnection() throws PropertyVetoException {
    cpds.setDriverClass("org.postgresql.Driver"); 
    cpds.setJdbcUrl("jdbc:postgresql://localhost:5432/myStockDatabase"); 
    cpds.setUser("myUserName"); 
    cpds.setPassword("myPassword"); 
    cpds.setInitialPoolSize(4);
    cpds.setMinPoolSize(4);
    cpds.setMaxIdleTime(30);
    cpds.setMaxPoolSize(MAX_CONNECTIONS);
}

public static Connection getConnection() {
    return cpds.getConnection();
}
}

However, when i get a connection from the connection pool above and try to use it with CopyManager like in the example below, the code doesn't work

Connection pooled_con = MyPooledConnection.getConnection();
CopyManager cm = new CopyManager((BaseConnection) pooled_con);
cm.copyIn("COPY prices FROM STDIN WITH DELIMITER AS ','", 
             new BufferedReader(new FileReader(filepath)), buffersize);

I'm guessing the issue is with the connection, but i can't seem to figure out what about it is different. I've tried catching the error with SQLException and IOException, but it doesn't catch either. Has anyone encountered this?

----UPDATED----

Thanks to a_horse_with_no_name the guidance on this. The following code worked for me

// Cast the connection as a proxy connection
C3P0ProxyConnection proxycon = (C3P0ProxyConnection)cpds.getConnection();
try {

    // Pass the getCopyAPI (from PGConnection) to a method
    Method m = PGConnection.class.getMethod("getCopyAPI", new Class[]{});
    Object[] arg = new Object[] {};

    // Call rawConnectionOperation, passing the method, the raw_connection, 
    // and method parameters, and then cast as CopyManager
    CopyManager cm = (CopyManager) proxycon.rawConnectionOperation(m,
                                         C3P0ProxyConnection.RAW_CONNECTION,arg);
    cm.copyIn("COPY prices FROM STDIN WITH DELIMITER AS ','", new BufferedReader(new 
                                                FileReader(filepath)), buffersize);
} catch (NoSuchMethodException | IllegalAccessException 
                        | IllegalArgumentException | InvocationTargetException e) {
    // Deal with errors here
}
like image 496
Jaycal Avatar asked Jan 26 '13 17:01

Jaycal


People also ask

What is c3p0 connection pool?

c3p0 is a Java library that provides a convenient way for managing database connections. In short, it achieves this by creating a pool of connections. It also effectively handles the cleanup of Statements and ResultSets after use.

How do I return connection to connection pool?

You need to close() it after calling commit(). Note that if you use a connection pool in this way, close() doesn't really close the connection (like when you make a direct connection to the database), it just returns the connection to the pool.

How does connection pooling work in PostgreSQL?

Connection pooling is the process of having a pool of active connections on the backend servers. These can be used any time a user sends a request. Instead of opening, maintaining, and closing a connection when a user sends a request, the server will assign an active connection to the user.

What is a connection pool data source?

DataSource objects that implement connection pooling also produce a connection to the particular data source that the DataSource class represents. The connection object that the getConnection method returns is a handle to a PooledConnection object rather than being a physical connection.


1 Answers

The pool does not give you the "native" connection, it always hands out a proxy object:

From the manual:

C3P0 wraps these Objects behind a proxies, so you cannot cast C3P0-returned Connections or Statements to the vendor-specific implementation classes

You probably can't use the CopyManager using C3P0. I'm not sure, but maybe you can use the workarounds described here: http://www.mchange.com/projects/c3p0/#raw_connection_ops

If that does not work you might want to use a different connection pool (e.g. the new Tomcat 7 JDBC-Pool) that gives you access to the underlying native connection.

like image 192
a_horse_with_no_name Avatar answered Oct 10 '22 22:10

a_horse_with_no_name