C3P0 Connection pool support

2 messages Options
Embed this post
Permalink
Saso Musevic

C3P0 Connection pool support

Reply Threaded More More options
Print post
Permalink
Hi all!

I tried to use C3P0 pool in combination with hibernate-spatial (build from latest source) and here is what happened:

Exception in thread "Main Thread" org.hibernatespatial.HibernateSpatialException: Couldn't get at the OracleSpatial Connection object from the PreparedStatement.
    at org.hibernatespatial.oracle.SDOGeometryType.findOracleConnection(SDOGeometryType.java :200)
    at org.hibernatespatial.oracle.SDOGeometryType.nullSafeSet(SDOGeometryType.java:95)
    at org.hibernatespatial.GeometryUserType.nullSafeSet(GeometryUserType.java:183)
    at org.hibernate.type.CustomType.nullSafeSet (CustomType.java:146)
    at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:1997)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java :2243)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2660)
    at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:56)
    at org.hibernate.engine.ActionQueue.execute (ActionQueue.java:250)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:234)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:141)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions (AbstractFlushingEventListener.java:298)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)

I checked C3P0 source and find out this:
  • C3P0 wraps all instances of java.sql.Connection with class com.mchange.v2.c3p0.impl.NewProxyConnection
  • C3P0 wraps all instances of java.sql.PreparedStatement with class com.mchange.v2.c3p0.impl.NewProxyPreparedStatement
  • generally, C3P0 wraps all java.sql.* with com.mchange.v2.c3p0.*
  • NewProxyConnection returns NewProxyPreparedStatement, NewProxyResultSet...
  • method "Object NewProxyConnection.rawConnectionOperation(Method, Object, Object[])" makes a call to underlying Connection instance (in our case that can only be PosgreConnection or OracleConnection, in above case it is OracleConnection)
  • above method is smart: if you try to make a call to, for example, OracleConnection.prepareStatement(String), it checks the return type and, in this case, wraps java.sql.PreparedStatement in com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.All resources, that are acquired this way are not cached/pooled by C3P0 (no statement caching/pooling)
Obviously, there is no way to get an instance of OracleConnection from it. One option is to wrap NewProxyConnection in a proxy class, that implements OracleConnection, delegating all Oracle specific calls via NewProxyConnection.rawConnectionOperation.
I did not do any performance checks, but it sounds like statement pooling can give a significant boost, so using C3P0 in spatial apps could make sense.

BTW: I still think, that the right way to solve this should be to make NewProxyConnection somehow extend OracleConnection.

Cheers,
   Saso Musevic,
      Ljubljana,
         Slovenia



_______________________________________________
hibernatespatial-users mailing list
[hidden email]
http://www.hibernatespatial.org/cgi-bin/mailman/listinfo/hibernatespatial-users
Karel Maesen

Re: C3P0 Connection pool support

Reply Threaded More More options
Print post
Permalink
Hi Saso,



On 21 Jan 2008, at 13:48, Saso Musevic wrote:

>
> I checked C3P0 source and find out this:
> C3P0 wraps all instances of java.sql.Connection with class  
> com.mchange.v2.c3p0.impl.NewProxyConnection
> C3P0 wraps all instances of java.sql.PreparedStatement with class  
> com.mchange.v2.c3p0.impl.NewProxyPreparedStatement
> generally, C3P0 wraps all java.sql.* with com.mchange.v2.c3p0.*
> NewProxyConnection returns NewProxyPreparedStatement,  
> NewProxyResultSet...
> method "Object NewProxyConnection.rawConnectionOperation(Method,  
> Object, Object[])" makes a call to underlying Connection instance  
> (in our case that can only be PosgreConnection or OracleConnection,  
> in above case it is OracleConnection)
> above method is smart: if you try to make a call to, for example,  
> OracleConnection.prepareStatement(String), it checks the return  
> type and, in this case, wraps java.sql.PreparedStatement in  
> com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.All resources,  
> that are acquired this way are not cached/pooled by C3P0 (no  
> statement caching/pooling)
>
> Obviously, there is no way to get an instance of OracleConnection  
> from it. One option is to wrap NewProxyConnection in a proxy class,  
> that implements OracleConnection, delegating all Oracle specific  
> calls via NewProxyConnection.rawConnectionOperation.
> I did not do any performance checks, but it sounds like statement  
> pooling can give a significant boost, so using C3P0 in spatial apps  
> could make sense.
>
> BTW: I still think, that the right way to solve this should be to  
> make NewProxyConnection somehow extend OracleConnection.

I've little knowledge of how C3P0 works, so I'm glad you're  
investigating this issue. I agree that the current strategy (using  
findOracleConnection) can't work with the C3P0 proxy. But I'm not  
sure if I entirely understand your proposed solution. Is the  
following an accurate description of what you propose?

1. in SDOGeometryType: retrieve the Connection from the  
PreparedStatement
2. wrap the connection in a dynamic proxy that implements  
OracleConnection
3. in the InvocationHandler of the proxy implement a strategy that  
calls the method on the wrapped connection
        a) either by locating the OracleConnection (as in the  
findOracleConnectio method) and calling the method on that object
        b) or by calling rawConnectionOperation (in case the connection is  
of type com.mchange.v2.c3p0.NewproxyConnection

If this is an accurate description, then we would keep this approach  
general and extensible to other cases where the OracleConnection is  
wrapped or proxied. Plus, we should avoid creating  compile  
dependencies on C3P0 libraries.

Regards,

Karel Maesen

_______________________________________________
hibernatespatial-users mailing list
[hidden email]
http://www.hibernatespatial.org/cgi-bin/mailman/listinfo/hibernatespatial-users