> [...] It is hardly finished, but perhaps some of the
> ideas in it could be adapted to Sergey's class to handle the
> awkwardness of connection closing.

This type of solution works well for methods that immediately execute
a query. For construction, a Connection is not needed and can be
supplied later using various means. If, however, the connection is
supplied, then it must be closed in various places, scattered across
the internal API. Think of creating an org.jooq.Cursor using
fetchLazy(), and then slowly iterating to the end of the cursor.
Similar issues are caused by fetchLater(), which execute
asynchronously.

While at first, adding many ResultQuery.fetchXXX() methods seemed like
a very convenient API, it now leads to many questions. The real
problem is probably the fact that query construction and query
execution both originate in the same Factory object. To thoroughly
separate those concerns, I have been planning to change the jOOQ
architecture towards the following facts for jOOQ 3.0 (due in late
2012):

1. The Factory is only used for Query and QueryPart construction. All
methods are static (including select(), insertInto(), etc), Factory
has no state.
2. Query objects can no longer execute themselves. They are no longer
"attached".
3. An "Executor" type is created. It inherits today's Factory's state
(Connection/DataSource, SQLDialect, Settings). It initiates query
rendering and binding contexts before executing any Query. It will
also inherit all sorts of fetch methods, which will no longer be on
the query object itself.

(the above is now tracked as https://sourceforge.net/apps/trac/jooq/ticket/1372)

This will lead to the following client code:

Result<?> r1 = executor.fetch(select(A, B).from(C));
int r2 = executor.execute(insertInto(C).values("A", "B"));

This design will resolve quite a few thread-safety issues as well.
Once constructed, the same Query object could be executed by several
threads / executors at the same time. Eric's solution involving
commands and custom exception factories will become applicable to the
Executor easily. Also, an Executor can base its operations on a JDBC
Connection or on a JDBC DataSource.

In the short run, however, I do think that Eric's ideas of the
Executor can be applied to Sergey's FactoryProxy. As a matter of fact,
I prefer the term "Executor" over "Proxy", thinking about long-term
plans.

> My motivation in writing it was that I was acculating a number of
> methods in some "service classes" which were doing JOOQ queries and I
> realized they had a lot of redundant boilerplate, and I wanted to
> encapsulate that somewhere. In particular the code to get and close
> connections, catch exceptions, and rethrow those as domain-specific
> exceptions. (That is what the "ExceptionFactory" is about...this may
> not be the right term for it...and if you don't provide one it just
> throws RuntimeExceptions wrapping the underlying exception).

Sergey also had the idea of writing something similar to your
ExceptionFactory. Those ideas were discussed in this thread:
https://groups.google.com/d/topic/jooq-user/v3PJRm5gs2E/discussion

I very much like the idea of a pluggable ExceptionHandler with a
default implementation.

Reply via email to