I replied from wrong email, please excuse me if this reaches the list twice.
On Tue, May 6, 2014 at 8:06 PM, tetsuo <[email protected]> wrote: > Since it's the same request, isn't (or couldn't be) the db connection the > same in size() and iterator() calls? If you created the temporary table in > one, isn't it still available to the other (so you could avoid recreating > it)? Well, the connection is being managed by spring transactional resource management classes. A transaction is demarcated with @Transactional(readOnly=true) on a particular method. All transactional resources are bound to thread during transaction execution and released when transaction finishes. One transactional resource is of course a connection. I have extended this framework to register temporary table names which are being automatically deleted on transaction finish. Each time you invoke a transactional method you perform following steps: - acquire a connection from the pool - bind connection to thread making all subsequent queries use same connection - start transaction - do some work - finish transaction (of course for read only there is nothing to be done) - release transactional resources - unbind connection from thread - release connection to the pool. using spring framework without spring managed transactions means you end up using different connection for EVERY sql query. My IDataProviders usually wrap spring bean with @Transactional(readOnly=true) methods. Unfortunatelly two method calls: size() and iterator() mean two different transaction and two different connections. I am unable to wrap any single point of entry with @Transactional - that probably would have to be some generic Wicket method call. I cannot bind a connection to current request thread preemptively because that would mean a huge resource hog - I would have to obtain a connection from pool for every request being made. Temporary tables have connection scope so not deleting the table on connection release means polluting the database server with lots of temporary tables as long as connection stays in pool (which could be indefinite). The temporary tables would be probably stale all the time - any ongoing transaction may probably alter what the temporary table should contain. Anyway any approach still feels like a hack and not resolving the problem at source. A single point of entry in IDataProvider: - allows the user to manage resources more efficiently. - gives user the option to resign from providing size() information - do you really go from 1st to 15th page that often or do you usually click "next results"? - gives user the option to provide "has more results" information without providing actual dataset size. Having a single point of entry IDataSource means also you can do: new IDataProviderSingleEntry<T( oldDataProvider ) { public Page<T> getPage( long first, long count ) { return new PageImpl<T>( oldDataProvider.interator( first, count ), oldDataProvider.size() ); } } This trivial decorator means IDataProviderSingleEntry and IDataProvider may even coexist in wicket-core and wicket-extensions. Some variation of this approach is actually used by inmethod-grid. Maybe we could unify the way all pageables access resources. -- Leszek Gawron
