Codegen error with H2

63 views
Skip to first unread message

jason....@gmail.com

unread,
Mar 4, 2015, 3:52:13 PM3/4/15
to jooq...@googlegroups.com
Hello JOOQ Folks, 

I'm having a bit of trouble with the code generation in JOOQ and I'm a little unsure of what I'm doing wrong.  I'm trying to build a library that scans our JPA entities, and does code generation on them.  I created my own generator that intercepts the generate(Database) call, scans the classpath for JPA entities, builds an H2 schema out of them with hibernates ddl tools, creates an H2 database and populates it with the schema, and pipes that to a delegate JavaGenerator.  I realize what I'm doing isn't super common so if I'm just not using JOOQ in a way it can be used, please let me know, I'm using both 3.5.3 for the core jooq modules and codegen.

The issue I'm having is that the generated code is trying to reference a static field on the generated table entity, when the actual field it should be hitting is on a singleton on that generated entity. From looking inside the JavaGenerator I don't think it's building the field access quite correctly, but I'm not sure if that's an artifact of what I'm doing.

Here's where I generate the code, and attached is the generated source.  I can provide the schema inside H2 if that is helpful as well. Apologies for the weird formatting.

//just a helper class that does the schema export into a h2 db

H2Database db = new H2Db(entityClasses).getDb();

       delegate.setTargetDirectory(config.getExportPath());

        delegate.setTargetPackage(pkg);

        db.setIncludes(new String[] { ".*" });

        db.setExcludes(new String[0]);

        db.setRecordVersionFields(new String[0]);

        db.setRecordTimestampFields(new String[0]);

        db.setSchemaVersionProvider(new ConstantSchemaVersionProvider("1"));

        db.setConfiguredEnumTypes(new ArrayList<EnumType>());

        db.setConfiguredForcedTypes(new ArrayList<ForcedType>());

        db.setConfiguredCustomTypes(new ArrayList<CustomType>());

        List<Schema> schemas = new ArrayList<Schema>();

        schemas.add(new Schema().withInputSchema("codegen").withOutputSchema("Generated"));

        db.setConfiguredSchemata(schemas);

        delegate.generate(db);


Please let me know if there's any additional context I should provide.  Thanks.
sources.tar.gz

Lukas Eder

unread,
Mar 5, 2015, 3:09:16 AM3/5/15
to jooq...@googlegroups.com
Hello

2015-03-04 21:05 GMT+01:00 <jason....@gmail.com>:
Hello JOOQ Folks, 

I'm having a bit of trouble with the code generation in JOOQ and I'm a little unsure of what I'm doing wrong.  I'm trying to build a library that scans our JPA entities, and does code generation on them.  I created my own generator that intercepts the generate(Database) call, scans the classpath for JPA entities, builds an H2 schema out of them with hibernates ddl tools, creates an H2 database and populates it with the schema, and pipes that to a delegate JavaGenerator.  I realize what I'm doing isn't super common so if I'm just not using JOOQ in a way it can be used, please let me know, I'm using both 3.5.3 for the core jooq modules and codegen.

It's not an entirely absurd idea. It's been done in the past:

And we're probably going to support this out of the box some time in the future:

In jOOQ 3.5, we've already added support for parsing XML meta data formats instead of hitting the database (e.g. to support vertabelo.com's ERD export format in jOOQ 3.6). Generating meta data from a JPA annotated schema is also a good use-case.

However, I wouldn't override the generator for this. You should implement a org.jooq.util.Database (from jooq-meta) instead.

The issue I'm having is that the generated code is trying to reference a static field on the generated table entity, when the actual field it should be hitting is on a singleton on that generated entity. From looking inside the JavaGenerator I don't think it's building the field access quite correctly, but I'm not sure if that's an artifact of what I'm doing.

I'm afraid I'm not sure what you're talking about :)
You'll have to provide more code to help us look through the issue. I don't know what static field, what entity, what singleton and what specific parts of the JavaGenerator you referred to.
 
Here's where I generate the code, and attached is the generated source.  I can provide the schema inside H2 if that is helpful as well. Apologies for the weird formatting.

//just a helper class that does the schema export into a h2 db

H2Database db = new H2Db(entityClasses).getDb();

       delegate.setTargetDirectory(config.getExportPath());

        delegate.setTargetPackage(pkg);

        db.setIncludes(new String[] { ".*" });

        db.setExcludes(new String[0]);

        db.setRecordVersionFields(new String[0]);

        db.setRecordTimestampFields(new String[0]);

        db.setSchemaVersionProvider(new ConstantSchemaVersionProvider("1"));

        db.setConfiguredEnumTypes(new ArrayList<EnumType>());

        db.setConfiguredForcedTypes(new ArrayList<ForcedType>());

        db.setConfiguredCustomTypes(new ArrayList<CustomType>());

        List<Schema> schemas = new ArrayList<Schema>();

        schemas.add(new Schema().withInputSchema("codegen").withOutputSchema("Generated"));

        db.setConfiguredSchemata(schemas);

        delegate.generate(db);


Please let me know if there's any additional context I should provide.  Thanks.

Yes, as much context as possible. I.e. what's H2Db? What's delegate?

Cheers,
Lukas 

Jason Ruckman

unread,
Mar 5, 2015, 11:16:57 AM3/5/15
to jooq...@googlegroups.com
Hello Lukas, 

Thanks for responding.  I can provide the source for the project if that would help (it's quite small and there's just a junit test that I'm running right now to test things out).  Would you like me to zip it up and attach it here?

Lukas Eder

unread,
Mar 5, 2015, 11:20:27 AM3/5/15
to jooq...@googlegroups.com
Yes. Or upload it on GitHub. Whatever you prefer.

--
You received this message because you are subscribed to the Google Groups "jOOQ User Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jooq-user+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Jason Ruckman

unread,
Mar 5, 2015, 11:26:33 AM3/5/15
to jooq...@googlegroups.com
In case it helps.  I've attached the project here (it's quite small).  If you mvn package it, it'll run the test that exercises the generator. 
prototype.tar.gz

Lukas Eder

unread,
Mar 5, 2015, 11:51:17 AM3/5/15
to jooq...@googlegroups.com
Thank you very much. I'll have a look into it as soon as possible

--

Jason Ruckman

unread,
Mar 5, 2015, 12:01:50 PM3/5/15
to jooq...@googlegroups.com
No problem, thanks for your time.

Lukas Eder

unread,
Mar 10, 2015, 12:42:27 PM3/10/15
to jooq...@googlegroups.com
Hi there.

Huh, this is very subtle. I've been able to debug through your examples and this is the fix:

    DefaultGeneratorStrategy s = new DefaultGeneratorStrategy();
    s.setInstanceFields(true);
    setStrategy(s);
    delegate.setStrategy(s);

This is a rather nasty caveat. This instance field property is duplicated between the Generator and GeneratorStrategy types. When you run the generation tool, this duplication will take place, but not when you use all that codegen API directly. I've registered an issue for this to make sure that the default values in both types are the same (true):

Having said so, I really strongly suggest that you don't proceed with your current solution, but write a simple org.jooq.util.Database implementation only, and then use the officially supported API for programmatic code generation:

I'm pretty sure that you'll hit other walls because we just never intended for users to work directly with those APIs (which we won't maintain in a backwards-compatible manner, by the way)

Jason Ruckman

unread,
Mar 16, 2015, 12:31:10 PM3/16/15
to jooq...@googlegroups.com
Gotcha, thanks Lukas.  I'll go ahead and try and put together a JPADatabase instead.  Again, thanks for your time.
Reply all
Reply to author
Forward
0 new messages