You're right, Factory was intentionally left "unserialisable" in the
first versions of jOOQ. Today, however, this is wrong. Serialisability
is being re-worked for jOOQ 1.5.7. I'll add some additional
integration tests to ensure your use case is working correctly.
Thanks for your feedback.
Lukas
2011/4/6 Sander Plas <sande...@gmail.com>:
That's a very nice use case for jOOQ! Is that project going to be
accessible publicly? I was recently thinking about documenting some
success stories of using jOOQ with other frameworks or in real-life
applications. On the other hand, such a nice jOOQ-Wicket integration
could even become part of jOOQ itself, as an optional jOOQ extension,
if you would be interested in sharing this? Of course, you would keep
the copy-right of this integration...
Cheers
Lukas
> I'm trying to use this simple project as a test case for the jOOQ/
> Wicket combination. If this works out right, i plan to use this for
> more (and bigger) projects.
That would be very nice to see!
> I'd be happy to share code of the integration part or even of a
> complete example application!
Sure. Tell me whenever you're ready for such a project. By this month,
I will hopefully succeed with a Maven integration. I'm getting a hand
by another jOOQ user on that topic. So creating a dependency to Wicket
should be rather easy.
> Do you have any idea when 1.5.7 will be available? Can i already test
> the new 'Attachable' functionality in the trunk version?
I could release early, as your reported issues concerning
serialisability are rather urgent. Say, by the end of next week? In
the mean time, you can always download the jOOQ trunk from here:
http://sourceforge.net/projects/jooq/develop
The "Attachable API" is functional. Integration tests are running
smoothly, so far. So you could already test serialising and
re-attaching Query and Record objects (pre-release bug reports would
be very welcome). But be aware of the fact that I might change some
API elements before releasing 1.5.7
Cheers
Lukas
> A quick release would be great off course but I don't want to rush
> you :) I'm already quite happy if i can experiment with the trunk
> version.
No worries. With the currently experienced trouble related to the
latest HSQLDB version, I'm pretty keen on releasing soon, myself:
http://groups.google.com/group/jooq-user/browse_thread/thread/a1e001b682d3c35
> Speaking of which, when i try to compile the current trunk
> version of jOOQ on my home PC, i get: [...]
>
> [... the warning ...]
Trunk is very hot at the moment :-)
I have experienced inconsistencies before, between compiling jOOQ with
Eclipse and with javac. I've come to the conclusion that either one
has some severe compiler bugs. I'm not sure which one actually does,
the issue is quite tricky. You can check out the bug details here, if
you're interested:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=340506
In any case, thanks for pointing that out to me. I was planning on
updating the wiki anyway, to document using jOOQ in a Netbeans
project. So I can fix this, soon:
https://sourceforge.net/apps/trac/jooq/ticket/389
> 1 error
I can reproduce the error as well. That shouldn't be. Thanks for the
hint. In the mean time, please use Eclipse on trunk. I'm not
supporting development with Netbeans, yet.
> Just to make sure i understand how this is supposed to work - i need
> to explicitly call [attachableobject].attach(newJooqFactory) before i
> try to use a deserialized jOOQ object, right?
The final API usage will include
- Factory.attach(Attachable... attachables).
- Factory.attach(Collection<Attachable> attachables).
> Would it be possible to add some kind of mechanism that
> "automatically" re-attaches objects to a new factory whenever
> necessary?
How would you do that? jOOQ doesn't know when / how objects are
serialised. I think that should be the client code's responsibility.
Unless you have an other idea?
> For instance, i can imagine that you could add some overridable method
> to the Factory class (a "factories" factory) that allows the user to
> define how a new factory should be created whenever needed so that
> whenever a jOOQ object discovers that it's detached, it can call that
> method to get a working factory. That way, a user could "ignore" the
> whole serialization/deserialization process.
You mean a central (static) Factory registry? jOOQ couldn't ensure
that all Factories in that registry hold valid (open, working) JDBC
Connections. I think, in your case, you will have to write a wrapper
around jOOQ for serialisation / deserialisation...
Cheers
Lukas
Fixed on trunk:
https://sourceforge.net/apps/trac/jooq/ticket/389
> Please tell me if i'm missing something obvious that makes this
> impossible ;)
What about various sessions? How does an Attachable know its session?
(both J2EE/HTTP/Wicket sessions AND database sessions)
I understand what you intend to do. I just don't see (yet) how it's
possible. Before continuing, I'm sure we agree that providing
registries is optional, and in case jOOQ couldn't find a registry, it
will still throw the DetachedException when an unattached object is
stored/refreshed/deleted/executed, right?
Of course, the registry's implementation is up to the user. jOOQ will
only provide an interface. But how does the magic happen? Say you have
an attachable A. And you have two databases DB1 and DB2. Now A is
available in both DB1 and DB2 (by the SchemaMapping functionality). Of
course, you are right, the attachables can hook into deserialisation,
so once they are materialised again, they will ask the registry for a
Configuration or Factory. But what can they pass to the registry? A,
for instance doesn't know whether it belonged to DB1 or DB2 anymore,
as that information was session-dependent, or in the scope of jOOQ's
client code. So how can the registry provide the correct
Configuration? Or is that entirely up to the client code?
Maybe, you could provide me with a descriptive prototype? Is this what you mean?
interface FactoryRegistry {
void attachMe(Attachable attachable) throws NotAttachableException;
}
2011/5/3 Sander Plas <sande...@gmail.com>:
> interface FactoryRegistry {
> void attachMe(Attachable attachable) throws NotAttachableException;
> }
How will the attachable find the correct registry? What does Wicket do
to discover these things? There are hundreds of possibilities, from
the simple JVM parameter, to JNDI, etc etc...
That's exactly what it's for.
> Even if you choose another approach than the FactoryRegistry one, i
> think the general idea should still be to delegate everything to the
> client code, for the simple reason that all those implementation
> details should be outside the scope of the jOOQ project, just as the
> creation of the initial JDBC connection is now.
Yes, because I really have better things to do, too :-)
OK, I got it now. I think I may find some solution in the near future,
about how to find a relevant registry instance.
I have scheduled a change:
https://sourceforge.net/apps/trac/jooq/ticket/485
If I can come up with an acceptable solution how to "discover" the
relevant registry, then this can make it in 1.5.9.
Cheers
Lukas
Well thanks for the interesting feedback!
Feel free to test the ConfigurationRegistry and provide feedback, when
you have time
https://sourceforge.net/apps/trac/jooq/wiki/Manual/JOOQ/Serializability
Cheers
Lukas
> Because i disconnect JDBC connections at the end of each HTTP request
> cycle to prevent them from 'leaking', this means that i end up with
> jOOQ objects that have references to disconnected JDBC connections.
> Since the jOOQ objects do not get deserialized, ConfigurationRegistry
> is not being called at all.
Does Wicket not manage your connections via DataSources, like a J2EE
container? Then you shouldn't need to worry about connections
yourself... J2EE containers usually have a shared connection pool for
these purposes, but I don't know Wicket.
> I was wondering if it would be possible to call the
> ConfigurationProvider.provideFor method just before query execution
> (when a jOOQ object is detached OR the associated JDBC connection is
> disconnected) instead of in readObject?
I'm sorry I forgot about that. I'll add a 1.6.0-SNAPSHOT version soon,
implementing this. I prefer attaching (if possible) at deserialisation
time, because some advanced data types (especially with Oracle) need
an open connection to be constructed. But there shouldn't be any
drawback in handling the other case, too.
https://sourceforge.net/apps/trac/jooq/ticket/535
> slightly off-topic: i tried to download the jOOQ source myself (both
> the current trunk version and r905, which is in fact release 1.5.9
> according to the subversion comments) to experiment with these kind of
> things, but i get this error when i try to compile it (maven in
> Netbeans):
>
> org/jooq/impl/InsertImpl.java:[109,20] reference to addValue is
> ambiguous, both method <T>addValue(org.jooq.Field<T>,T) in
> org.jooq.StoreQuery<R> and method
> <T>addValue(org.jooq.Field<T>,org.jooq.Field<T>) in
> org.jooq.StoreQuery<R> match
Thank you for mentioning this. I keep forgetting about Netbeans. It
seems that Eclipse, Netbeans and Maven don't have exactly the same
compiler behaviour when overloaded generic methods are involved, when
<T> binds to Object. This is a rather complex topic.
In the mean time, you could try with Eclipse...?
Cheers
Lukas
You're right, that's how it's done. The close() method is intercepted
by the J2EE container.
> Thanks. Could you also test whether the JDBC connection is still
> connected and call provideFor() when the connection isn't?
That might work. On the other hand, I don't feel the opened/closed
state of a Connection should be in jOOQ's responsibility (I'm not even
sure whether isClosed() is implemented in all JDBC drivers). As an
alternative, check out line 69 in
http://jooq.svn.sourceforge.net/viewvc/jooq/jOOQ/src/main/java/org/jooq/impl/AbstractQuery.java?revision=908&view=markup
What about if jOOQ just always calls provideFor() before every query
execution, so you can run those (and additional) checks yourself? You
(client code) know more about what's a good Connection and what is
not. If I get a new Configuration through provideFor(), I'll use that.
Otherwise, the existing Configuration will have to do. And we'll leave
the original calls to provideFor() on deserialisation of a Connection.
I somehow feel, this will be the cleanest solution. What do you think?
Lukas
Feel free to check up on that solution using the latest SNAPSHOT:
https://oss.sonatype.org/content/repositories/snapshots/org/jooq/
Cheers
Lukas
Nice!
Thanks for feedback.
Cheers Lukas