JOOQ metamodel generation directed by JPA annotations

484 views
Skip to first unread message

Pedro Pastor

unread,
May 31, 2012, 9:33:51 AM5/31/12
to jOOQ User Group, peri...@yahoo.es
JOOQ offers this:
*
"jooq-codegen configuration"
<!-- Annotate POJOs and Records with JPA annotations for increased
compatibility and better integration with JPA/Hibernate, etc
Defaults to false -->
<jpaAnnotations>false</jpaAnnotations>
*
"Generated or custom POJO's instead of jOOQ's Records"
If you're using jOOQ along with Hibernate / JPA, or if you want to
use your
own, custom domain-model instead of jOOQ's Record type-hierarchy, you
can
choose to select values into POJOs. Let's say you defined a POJO for
authors:
But, I want this:

I would like to INTEGRATE my domain class, the validation/restrictions
declaration (annotations) of that class,
and the persistence metadata (annotations) of that class in one place:
the SAME domain class.
[Yes, I know it: it breaks OO's principles of separation of concepts
and layers]

I would like that JOOQ metamodel generator takes that domain class,
analize it, and generate
the corresponding JOOQ classes, based on the presistence annotations.
So, there will NOT be
connection to a database.
[Yes, I know it: this breaks JOOQ's philosophy of "db is the the first
one"]

For the validation/restrictions declaration I was think in Bean
Validation (JSR 303), although it's
a transparent thing for this situation.
For the persistence metadata, I was think in JPA 2.0 (JSR 317),
although I would serve any basic
annotation of kind of @Table, @Column, etc. It would be a simplified
JPA: no @Entity, no @ManyToMany,
etc. We need the minimal information to generate the JOOQ metamodel.

Advantages:
* Declaration of validation, persistence, and model in a unique place.
Therefore:
** Development productivity enhancement, because all relevant code is
localized in one place, and apporting very little information.
** Bugs and errors (due to software layers synchronization
maintenance) probability reduction.
Disadvantages:
* Class model without inheritance.
* Class model relations are solely 1:1.


CONCLUSSION:

It would possible implements an option in JOOQ that let to generate
the metamodel directly from JPA annotations in classes, without
connecting with DB?
Or, better: It would be possible to check both sides: annotations
and DB schema! If there would be differences, then generator alerts
to user!

Lukas Eder

unread,
May 31, 2012, 10:43:40 AM5/31/12
to jooq...@googlegroups.com
Hello,

N.B: I would like to invite other users on this group to participate
in this interesting discussion!

> [Yes, I know it: it breaks OO's principles of separation of concepts
> and layers]

I don't mind that in generated source code.

> [Yes, I know it: this breaks JOOQ's philosophy of "db is the the first
> one"]

Others have proven valid reasons to me, why this philosophy is not
untouchable, even in the jOOQ world. Most importantly, Sergey Epik has
suggested this several times on the user group, asking for a clean
separation of what he called "introspection" and "generation" phases.
This can be seen in the following thread:
https://groups.google.com/d/topic/jooq-user/4-iZMVDtkGA/discussion

> Advantages:
> * Declaration of validation, persistence, and model in a unique place.

That's what your database schema (from a jOOQ perspective) offers,
too. A unique place for all your data model (including validation,
constraints, etc.)

> ** Development productivity enhancement, because all relevant code is
> localized in one place, and apporting very little information.

Who will generate the DDL / migration scripts from your annotated
objects? Would you use Hibernate for that? I think you won't be able
to have some parts of your domain being externalised to SQL scripts.

> ** Bugs and errors (due to software layers synchronization
> maintenance) probability reduction.

I'm not sure what you mean by that

> Disadvantages:
> * Class model without inheritance.
> * Class model relations are solely 1:1.

True

> It would possible implements an option in JOOQ that let to generate
> the metamodel directly from JPA annotations in classes, without
> connecting with DB?

You could implement your own Generator. As a matter of fact, for what
you want to achieve, you could even use Hibernate's code-generator
along with velocity templates to generate jOOQ artefacts such as the
schema and the tables.

As a result of Sergey's requests, I have recently tried to dump the 13
supported databases as an INFORMATION_SCHEMA.xml, or TABLES.csv,
COLUMNS.csv, REFERENTIAL_CONSTRAINTS.csv, etc. and read those files
instead of reading from the database. This turned out to be a lot more
work than I expected, if I want this type of source code generation to
remain feature complete (including Routine, UDT, ARRAY support, etc)

Generating source code from JPA/JSR-303 annotated beans is pretty much
the same as generating source code from XML/CSV files, except that the
domain model is no longer a SQL/relational one, but an object-oriented
one. I like those ideas, but when you go in-depth, they become very
hard to do right. For instance, what if your JPA-annotated model uses
inheritance? What if your JPA-annotated model uses @JoinTable,
@DiscriminatorColumn, @Embeddable, @Embedded, @IdClass,
@CollectionTable, @Enumerated, etc. etc. jOOQ could quickly support
simple code generation from @Table, @Column and other simple
annotations. But once that's in place, users would expect more and
perceive things not to be working correctly. Is that worth the
trouble? The question goes to the whole user group.

So before we continue this discussion, please tell me why you prefer
jOOQ over Hibernate / QueryDSL and other tools that already implement
JPA, when you don't want to place your main data schema authority in
the database?

Note, some users have successfully used jOOQ and Hibernate together
(Hibernate for the CRUD and some simple queries, jOOQ for the
"hard-core" SQL). Isn't that a more suitable approach for you, right
now?

> Or, better: It would be possible to check both sides: annotations
> and DB schema! If there would be differences, then generator alerts
> to user!

Hehe, yes. Looking forward to pull requests! ;-)

Cheers
Lukas

2012/5/31 Pedro Pastor <pedropasto...@gmail.com>:

Pedro Pastor

unread,
Jun 1, 2012, 4:18:29 AM6/1/12
to jOOQ User Group
Thank you, Lukas, for your rapid response.
In my opinion:
Good JPA 2.0 things (in my opinion):
* Java standard.
* You can declare database mertadata by annotations.
* Admits a metamodel based in classes.
* Typesafe queries with a criteria API.
Bad JPA 2.0 things (in my opinion):
* Adds an abstraction level on top of SQL: no control over
generated SQL, cache mechanism (entity manager), etc.
* The criteria API is horrendous, very far of SQL syntax.
I would like, ideally:
* Java standard.
* You can declare database mertadata by annotations.
LOGICALLY, I'M RESPONSIBLE OF MANTAIN SYNCHRONIZED MY
DATABASE AND MY ANNOTATIONS.
* Admits a metamodel based in classes.
* Typesafe queries with a fluent SQL-like syntax: JOOQ
* Direct emission of SQL sentences (no cache, no sw layer).

Do you understand my point of view?

Lukas Eder

unread,
Jun 1, 2012, 5:24:36 AM6/1/12
to jooq...@googlegroups.com
Hi Pedro,

Thanks for your clarifications

> Do you understand my point of view?

Yes I do. Even if I don't entirely agree with you :-)

> Good JPA 2.0 things (in my opinion):
> * Java standard.

Yes. Unfortunately, though, a very invasive one

> * You can declare database mertadata by annotations.

Partially, yes. For rather simple relational schemata, this works. For
true SQL (incuding compound primary keys, check constraints, triggers,
auto-generated values from stored procedures, sophisticated indexes,
IOT, partitioning, custom storage clauses, etc.) it doesn't work. But
in many cases, this can be ignored, I agree.

> * Admits a metamodel based in classes.

Yes. But then, again, you're not doing SQL. We could start a religious
discussion here ;-) ... which we won't

> * Typesafe queries with a criteria API.

Type-safety is nice. It works well for checking syntax correctness
(DSL) and field/column type checking to some extent

As far as I understand, though, JPA also pretends to offer type-safety
on a record-level, which highly limits SQL features and scope. True
record-level type-safety cannot be simulated in Java, short of formal
support for tuple and record types. However, I was thrilled to see
Brian Goetz's recent mentioning of such ideas on the lambda-dev
mailing list, using a hash operator #:

http://mail.openjdk.java.net/pipermail/lambda-dev/2012-May/004979.html

The ideas include
#(a, b) // Tuple
#(a: 3, b: 4) // Record

If this is supported by the Java language, then true type-safety can
finally be implemented in SQL abstraction APIs like JPA or jOOQ. Scala
already simulates tuples, which leads to some increased typesafety.

> Bad JPA 2.0 things (in my opinion):
> * Adds an abstraction level on top of SQL: no control over
> generated SQL, cache mechanism (entity manager), etc.

Indeed. It doesn't run SQL, it runs JPQL, yet another QL highly
inferior to SQL, just like OQL, JPOQL, HQL, and many others.

> * The criteria API is horrendous, very far of SQL syntax.

I couldn't agree more on this one ;-) It's even quite far from the
JPQL syntax, which it really generates.

> I would like, ideally:
> * Java standard.
> * You can declare database mertadata by annotations.
> LOGICALLY, I'M RESPONSIBLE OF MANTAIN SYNCHRONIZED MY
> DATABASE AND MY ANNOTATIONS.
> * Admits a metamodel based in classes.
> * Typesafe queries with a fluent SQL-like syntax: JOOQ
> * Direct emission of SQL sentences (no cache, no sw layer).

I see. In the short run, if you really want to use jOOQ right now,
you'll probably have to resort to some tricks involving the Hibernate
code generator. For instance, you could:

- Define your annotated entities
- Generate an HSQLDB or H2 database from those entities
- Use jOOQ to generate jOOQ artefacts from that temporary database

In the long run, here's my point of view:

jOOQ is now quite mature and getting more and more popular. One of my
long-term goals is indeed to closely interact with JPA, as I do
believe that Java standards are a good thing, too, at least to some
extent. Already today, you can fetch data into your custom
JPA-annotated beans. Your suggestions go in a similar direction.

Also, source code generation from an "offline" database schema
definition (XML, CSV, annotated Java classes) is a good idea, as it
leads to better development processes.

While I do not agree that those "offline" database schema definitions
should be the primary schema definition as you will lose a lot of
features and scope from what a database really offers, I can see that
for some users, this is still an acceptable approach.

Besides, supporting your idea will help make jOOQ more suitable for
those that want to couple jOOQ and Hibernate/JPA.

From many recent feature requests, I start to realise that I will have
to completely re-engineer jooq-meta and jooq-codegen, allowing for
providing "plugins" as a schema source. Users (such as you) could
contribute new schema sources and code-generation targets. Those
"plugins", however, will not be part of the official jOOQ
distribution:

1) because there might be too many
2) because they're hard to integration-test
3) because I probably often won't agree with them :-)
4) because jooq-codegen / jooq-meta are nice additions to the jOOQ
core. I would really prefer to spend less time on code generation :-)
There are a lot of SQL features on the roadmap that I would prefer to
implement.

Yet, "plugins" allow for much more flexibility when using jOOQ.

I hope you understand that these things will not be implemented before
jOOQ 3.0 (hopefully in late 2012), though. I will track these ideas as
#1464:

https://sourceforge.net/apps/trac/jooq/ticket/1464

Any contributions are very welcome, too.

Cheers
Lukas

2012/6/1 Pedro Pastor <pedropasto...@gmail.com>:

Pedro Pastor

unread,
Jun 1, 2012, 8:56:41 AM6/1/12
to jOOQ User Group
Thank you, Lukas, for the interest
and time spent in this question.
Reply all
Reply to author
Forward
0 new messages