Pakcage specification for org.jooq.util.jpa.JPADatabase with Gradle

554 views
Skip to first unread message

Dominik Gruntz

unread,
Oct 19, 2016, 12:39:25 PM10/19/16
to jOOQ User Group
I try to generate code from JPA entities using the "database" org.jooq.util.jpa.JPADatabase, but I am working with the JOOQ-Gradle-Plugin provided by Etienne Studer (https://github.com/etiennestuder/gradle-jooq-plugin).


The question is how the list of packages containing the JPA entities can be specified. I have tried the following specification:

jooq {
    sample(sourceSets.main) {
        generator {
            name = 'org.jooq.util.DefaultGenerator'
            strategy {
                name = 'org.jooq.util.DefaultGeneratorStrategy'
            }
            database {
                name = 'org.jooq.util.jpa.JPADatabase'
                packages = 'com.example.jpa'
            }
            generate {
            }
            target {
                packageName = 'com.example.db'
                directory = 'src/main/java'
            }
        }
    }
}

 If I use the following definition, then Gradle prints the following error message:

* What went wrong:
A problem occurred evaluating root project 'spring-gs-jooq'.
> Invalid property: 'packages' on extension 'jooq.sample.generator.database', value: com.example.jpa

and if I drop the package property altogether then I get (as expected) the warning

No packages defined      : It is highly recommended that you provide explicit packages to scan

followed by the exception

org.jooq.exception.DataAccessException: Error while exporting schema
        at org.jooq.util.jpa.JPADatabase.create0(JPADatabase.java:111)
        at org.jooq.util.AbstractDatabase.create(AbstractDatabase.java:209)
        at org.jooq.util.AbstractDatabase.create(AbstractDatabase.java:201)
        at org.jooq.util.AbstractDatabase.getDialect(AbstractDatabase.java:183)
        at org.jooq.util.JavaGenerator.generate(JavaGenerator.java:209)
        at org.jooq.util.GenerationTool.run(GenerationTool.java:426)
        at org.jooq.util.GenerationTool$run.call(Unknown Source)


Any help is appreciated.
Thanks!
Dominik

Lukas Eder

unread,
Oct 20, 2016, 7:33:30 AM10/20/16
to jooq...@googlegroups.com
Hi Dominik,

Thank you very much for your enquiry. The use of the JPADatabase is documented here (only maven syntax, but gradle should be equivalent):

<generator>
    <database>
        <name>org.jooq.util.jpa.JPADatabase</name>
        <properties>
            <!-- A comma separated list of Java packages, that contain your entities -->
            <property>
                <key>packages</key>
                <value>com.example.entities</value>
            </property>
        </properties>
    </database>
</generator>

If a "database" requires additional arguments like in this case the packages containing entities, this is done through a generic properties "hashmap". In your case, you would probably need to write:

jooq {
    sample(sourceSets.main) {
        generator {
            name = 'org.jooq.util.DefaultGenerator'
            strategy {
                name = 'org.jooq.util.DefaultGeneratorStrategy'
            }
            database {
                name = 'org.jooq.util.jpa.JPADatabase'
                properties {
                    property {
                        key = 'packages'
                        value = 'com.example.jpa'
                    }
                }
            }
            generate {
            }
            target {
                packageName = 'com.example.db'
                directory = 'src/main/java'
            }
        }
    }
}

Please, let me know if this helps.
Best Regards,
Lukas

--
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+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Dominik Gruntz

unread,
Oct 20, 2016, 8:31:48 AM10/20/16
to jOOQ User Group
Hi Lunkas,
thank you very much for your help. The package definition works as you described, at least the warning 

No packages defined      : It is highly recommended that you provide explicit packages to scan

disappeared, and the build runs with two warnings (where the first ist obvious).

> gradle generateSampleJooqSchemaSource
:generateSampleJooqSchemaSource
HHH000181: No appropriate connection provider encountered, assuming application
will be supplying connections
HHH000342: Could not obtain connection to query metadata : The application must
supply JDBC connections

BUILD SUCCESSFUL

The process also generated artifacts in the specified directory, but no artifacts for the defined JPA classes, i.e. file Keys.java is empty but Tables.java contains a very long list of tables:

public class Tables {
public static final QueryStatistics QUERY_STATISTICS = com.example.jooq.information_schema.tables.QueryStatistics.QUERY_STATISTICS;
public static final SessionState SESSION_STATE = com.example.jooq.information_schema.tables.SessionState.SESSION_STATE;
public static final Locks LOCKS = com.example.jooq.information_schema.tables.Locks.LOCKS;
public static final Sessions SESSIONS = com.example.jooq.information_schema.tables.Sessions.SESSIONS;
public static final Triggers TRIGGERS = com.example.jooq.information_schema.tables.Triggers.TRIGGERS;
public static final Domains DOMAINS = com.example.jooq.information_schema.tables.Domains.DOMAINS;
public static final Constants CONSTANTS = com.example.jooq.information_schema.tables.Constants.CONSTANTS;
public static final FunctionColumns FUNCTION_COLUMNS = com.example.jooq.information_schema.tables.FunctionColumns.FUNCTION_COLUMNS;
public static final Constraints CONSTRAINTS = com.example.jooq.information_schema.tables.Constraints.CONSTRAINTS;
public static final CrossReferences CROSS_REFERENCES = com.example.jooq.information_schema.tables.CrossReferences.CROSS_REFERENCES;
public static final InDoubt IN_DOUBT = com.example.jooq.information_schema.tables.InDoubt.IN_DOUBT;
public static final Views VIEWS = com.example.jooq.information_schema.tables.Views.VIEWS;
public static final Collations COLLATIONS = com.example.jooq.information_schema.tables.Collations.COLLATIONS;
public static final ColumnPrivileges COLUMN_PRIVILEGES = com.example.jooq.information_schema.tables.ColumnPrivileges.COLUMN_PRIVILEGES;
public static final TablePrivileges TABLE_PRIVILEGES = com.example.jooq.information_schema.tables.TablePrivileges.TABLE_PRIVILEGES;
public static final Schemata SCHEMATA = com.example.jooq.information_schema.tables.Schemata.SCHEMATA;
public static final FunctionAliases FUNCTION_ALIASES = com.example.jooq.information_schema.tables.FunctionAliases.FUNCTION_ALIASES;
public static final Rights RIGHTS = com.example.jooq.information_schema.tables.Rights.RIGHTS;
public static final Roles ROLES = com.example.jooq.information_schema.tables.Roles.ROLES;
public static final Users USERS = com.example.jooq.information_schema.tables.Users.USERS;
public static final Sequences SEQUENCES = com.example.jooq.information_schema.tables.Sequences.SEQUENCES;
public static final Help HELP = com.example.jooq.information_schema.tables.Help.HELP;
public static final Settings SETTINGS = com.example.jooq.information_schema.tables.Settings.SETTINGS;
public static final Catalogs CATALOGS = com.example.jooq.information_schema.tables.Catalogs.CATALOGS;
public static final TypeInfo TYPE_INFO = com.example.jooq.information_schema.tables.TypeInfo.TYPE_INFO;
public static final TableTypes TABLE_TYPES = com.example.jooq.information_schema.tables.TableTypes.TABLE_TYPES;
public static final Indexes INDEXES = com.example.jooq.information_schema.tables.Indexes.INDEXES;
public static final Columns COLUMNS = com.example.jooq.information_schema.tables.Columns.COLUMNS;
public static final com.example.jooq.information_schema.tables.Tables TABLES = com.example.jooq.information_schema.tables.Tables.TABLES;
}


No idea where this information comes from, and no Idea why the annotated JPA entity classes do not appear.

Btw, the Gradle Plugin I am using is based on jOOQ 3.6.2 (see https://github.com/etiennestuder/gradle-jooq-plugin).

Hopefully you can give me another hint.

Best wishes
Dominik

Lukas Eder

unread,
Oct 20, 2016, 9:28:47 AM10/20/16
to jooq...@googlegroups.com
Hi Dominik,

Thanks for your quick reply. I will comment inline

2016-10-20 14:31 GMT+02:00 Dominik Gruntz <dominik...@fhnw.ch>:
Hi Lunkas,
thank you very much for your help. The package definition works as you described, at least the warning 

No packages defined      : It is highly recommended that you provide explicit packages to scan

disappeared,

Excellent!
 
and the build runs with two warnings (where the first ist obvious).

> gradle generateSampleJooqSchemaSource
:generateSampleJooqSchemaSource
HHH000181: No appropriate connection provider encountered, assuming application
will be supplying connections
HHH000342: Could not obtain connection to query metadata : The application must
supply JDBC connections

BUILD SUCCESSFUL

Hmm, interesting. I'm not sure if those warnings are really necessary / correct in Hibernate. jOOQ's JPADatabase uses Hibernate behind the scenes, and in the past, it was not trivial to get this right as Hibernate keeps changing these APIs backwards-incompatibly:

In any case, I'll try to fix Hibernate API usage in JPADatabase to get rid of these warnings:

Thanks for letting me know.
Hmm, that's really interesting. The way this works is that jOOQ uses Hibernate to generate an H2 database from your JPA annotated entities. It then proceeds with "ordinary" generation of content from that H2 database, including the built-in INFORMATION_SCHEMA. That's a side effect, that is probably not generally desired. I've created an issue for this:

As a workaround, you can specify the <inputSchema/> configuration to include only your schema.

Is there no other schema being generated? Are those JPA-annotated entities on the jOOQ code generator's classpath?
 
Btw, the Gradle Plugin I am using is based on jOOQ 3.6.2 (see https://github.com/etiennestuder/gradle-jooq-plugin).

There are certain limitations that derive from this Gradle Plugin limitation. I really hope this improvement will make it soon into the plugin:

It appears that Etienne is very busy with more pressing work at Gradle, unfortunately. There's always the possibility of falling back to using the standalone code generator from within Gradle (using the latest jOOQ version):

or to using Maven instead...

I hope this helps. Thanks again for all your feedback, that's very useful. If you have any additional questions, please do not hesitate to ask and I'm very happy to help
Lukas

Dominik Gruntz

unread,
Oct 20, 2016, 12:07:31 PM10/20/16
to jOOQ User Group
Great! Thanks for the immediate feedback and help!

> As a workaround, you can specify the <inputSchema/> configuration to include only your schema.
OK. Specification of
     inputSchema = 'PUBLIC' 
in the database section of the generator is possible and prevents generation of classes for tables in the information_schema.

> Are those JPA-annotated entities on the jOOQ code generator's classpath?
Good question. No, these classes were not on the class path! I just added them, and now code is generated, and due to the above inputSchema definition only for the public schema.

> There's always the possibility of falling back to using the standalone code generator from within Gradle (using the latest jOOQ version):
I tried to invoke the converter from the command line as described in http://www.jooq.org/doc/3.8/manual/getting-started/tutorials/jooq-in-7-steps/jooq-in-7-steps-step3/, but I gave up at some point as I had to add too many jar files on the class path (the whole dependency to hibernate in case of the JPADatabase).

But my example works now, which is great!
I will demonstrate that in the next lecture (in a course on JPA...)

Thanks again
Dominik


Lukas Eder

unread,
Oct 20, 2016, 3:47:23 PM10/20/16
to jooq...@googlegroups.com
Hi Dominik

Thanks a lot for your feedback. I'm happy to hear that it works now for you.

You're right of course, my bad. With jOOQ's standalone features, there aren't any dependencies, in case of which the standalone code generator works well, but the jOOQ-meta-extensions module has those dependencies and their transitive dependencies...

You could still use the standalone code generator from within Gradle, though, in case of which the code generator inherits Gradle's class path, but I guess that's no longer needed now.

Excellent, I'd be very curious to learn more about your lecture's content. Are your slides available online, somewhere? Btw: I'm passing FHNW just now on a train to Zurich :-)

Best Regards,
Lukas

TS TS

unread,
Nov 11, 2016, 2:01:55 PM11/11/16
to jOOQ User Group
Hello,
I have problem with JPADatabase generator and Gradle too. I know how to add packages property owing this topic. But it finish with:
java.lang.NullPointerException
at org.jooq.util.jpa.JPADatabase.create0(JPADatabase.java:79)
at org.jooq.util.AbstractDatabase.create(AbstractDatabase.java:209)

JPADatabase.java:79: String packages = getProperties().getProperty("packages");

How properies can be null here? My build.gradle looks like this:

buildscript {
   /*...*/
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath 'nu.studer:gradle-jooq-plugin:1.0.5'
classpath 'mysql:mysql-connector-java:6.0.3'
classpath 'org.jooq:jooq-meta-extensions:3.8.0'
}
}
/*...*/
       generator {
name = 'org.jooq.util.DefaultGenerator'
strategy {
name = 'org.jooq.util.DefaultGeneratorStrategy'
}
database {
name = 'org.jooq.util.jpa.JPADatabase'
properties {
property {
key = 'packages'
value = 'com.example.jpa'
}
}
}
generate {
}
target {
}
}

Lukas

To unsubscribe from this group and stop receiving emails from it, send an email to jooq-user+...@googlegroups.com.

Lukas Eder

unread,
Nov 12, 2016, 9:12:13 AM11/12/16
to jooq...@googlegroups.com
Hello,

I suggest upgrading to the latest nu.studer:gradle-jooq-plugin version, which is 2.0.2:

There had been a variety of fixes just recently related to this third party plugin's hard-wiring of the jOOQ version to 3.6.2, I believe.

Hope this helps,
Lukas

To unsubscribe from this group and stop receiving emails from it, send an email to jooq-user+unsubscribe@googlegroups.com.

TS TS

unread,
Nov 12, 2016, 12:58:46 PM11/12/16
to jOOQ User Group, dominik...@fhnw.ch, dominik...@gmail.com
Thanks Lukas, it helped.
I modified dependencies also:
jooqRuntime "org.jooq:jooq-meta-extensions:${jooqVersion}"
jooqRuntime "commons-logging:commons-logging:1.2"
Now it generates all schemas(public_, information_schema) but without my tables. @Dominik, how did you added them for plugin classpath?

Lukas Eder

unread,
Nov 12, 2016, 4:04:12 PM11/12/16
to jooq...@googlegroups.com
Hello,

It should work as documented in the third party plugin:

Have you tried those instructions?

Cheers,
Lukas

To unsubscribe from this group and stop receiving emails from it, send an email to jooq-user+unsubscribe@googlegroups.com.

TS TS

unread,
Nov 13, 2016, 3:08:39 AM11/13/16
to jooq...@googlegroups.com
Yes, of course. And I have been using it before with mysql codegen without problems. But now, with jpa codegen, it doesn't work for me.

--
You received this message because you are subscribed to a topic in the Google Groups "jOOQ User Group" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/jooq-user/2yvcZ1Vh_Bs/unsubscribe.
To unsubscribe from this group and all its topics, send an email to jooq-user+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--

pozdrawiam,
Tomasz Skowroński

Lukas Eder

unread,
Nov 13, 2016, 1:10:13 PM11/13/16
to jooq...@googlegroups.com
Hmm, interesting. I suspect this might be an issue in the gradle plugin (or in gradle in general) related to how the properties object is set to the Configuration. You've mentioned this:

java.lang.NullPointerException
at org.jooq.util.jpa.JPADatabase.create0(JPADatabase.java:79)
at org.jooq.util.AbstractDatabase.create(AbstractDatabase.java:209)

JPADatabase.java:79: String packages = getProperties().getProperty("packages");

I don't see how that getProperties() element can return null, except if someone (or some gradle magic) explicitly sets it to null on the JPADatabase object.

Have you tried debugging through the code generator?
Best Regards,
Lukas

TS TS

unread,
Nov 13, 2016, 1:34:01 PM11/13/16
to jooq...@googlegroups.com
I didn't try but yes, it was plugin issue (upgrade solve it).
Now it generates code from all schemas (public_, information_schema) but without my tables. 

Lukas Eder

unread,
Nov 13, 2016, 1:47:02 PM11/13/16
to jooq...@googlegroups.com
Is the package containing your entities on the classpath? I.e.:

value = 'com.example.jpa'

The JPADatabase uses Spring and Hibernate behind the scenes to scan your classpath for entities in that package, but it can find them only if they are on your classpath...

Dominik Gruntz

unread,
Nov 13, 2016, 7:55:31 PM11/13/16
to jOOQ User Group, dominik...@fhnw.ch, dominik...@gmail.com
> @Dominik, how did you added them for plugin classpath?
As Lukas wrote, your entities have to be on the classpath as well. For me the following gradle script worked to generate the JOOQ metadata classes:

buildscript {
repositories {
mavenCentral()
jcenter()
}
dependencies {
   classpath("nu.studer:gradle-jooq-plugin:1.0.6")
   classpath("org.jooq:jooq-meta-extensions:3.8.4")
  classpath files('bin')
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.4.1.RELEASE")
}
}

As I was working with Eclipse, the class files of my JPA Entities got stored in the bin directory. If I use this declaration, then the schemas public_ and information_schema are handled. The entity classes are then contained in package com.example.jooq.public_.tables.

As you might be interested in the public schema only, you could restrict the metadata generation to this schema by defining the inputSchema property to 'PUBLIC' in the jooq.generator.database section:

            database {
                name = 'org.jooq.util.jpa.JPADatabase'
                 properties {
                    property {
                        key = 'packages'
                        value = 'com.example.model'
                    }
                }
                inputSchema = 'PUBLIC' 
            }

With this definition the JOOQ metadata of my entity classes were generated in package com.example.jooq.tables.

Hope this helps. However I have to add the comment that I also get errors if newer versions of the plugins are used. I originally had defined the dependency to the jooq plugin as nu.studer:gradle-jooq-plugin:+, but at some day the build did no longer work (as the newest version of the plugin was  used).

Best wishes
Dominik

david...@gmail.com

unread,
Dec 28, 2016, 12:46:46 PM12/28/16
to jOOQ User Group
I am having a different problem with JPA annotation generation.  I'm new to jOOQ, so I may be missing something obvious, but it appears the org.jooq.util.jpa.JPADatabase class doesn't exist.  I can't find a org.jooq.util.jpa package at all.  Any help will be appreciated.  I have the latest jooq-3.9.0 jar.

Thanks,
David 

Lukas Eder

unread,
Dec 28, 2016, 12:50:39 PM12/28/16
to jooq...@googlegroups.com
Hi David,

Have you added the jooq-meta-extensions dependency?

Cheers,
Lukas

--

David Bal

unread,
Dec 28, 2016, 1:00:30 PM12/28/16
to jooq...@googlegroups.com
That solved the problem.  Thanks for the super-quick response.  ☺

--
You received this message because you are subscribed to a topic in the Google Groups "jOOQ User Group" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/jooq-user/2yvcZ1Vh_Bs/unsubscribe.
To unsubscribe from this group and all its topics, send an email to jooq-user+unsubscribe@googlegroups.com.

Lukas Eder

unread,
Dec 28, 2016, 1:18:25 PM12/28/16
to jooq...@googlegroups.com
Glad it helped! :)
Reply all
Reply to author
Forward
0 new messages