javamavenjooqquerydsljooq-codegen-maven

JOOQ failed to generate souces if pojo and DAO was in same package


My pojo(JPA entities) and DAO was in same package, I configured jooq-codegen-maven to generate TableImpl code from JPA entities. and DAO's code uses TableImpl.

the strange thing is ,

  1. when the first time I compile (mvn clean and install), the codegen will fetch 0 tables . And my DAO will get compile error (unknown class) because the TableImpl was not created. And the compile process of JPA entities(in same package) was skipped.

  2. Now, If I comment-out all DAO code and compile. Jooq also fetch 0 tables, but the other code of the package (including 9 JPA entities) will compile success

  3. I have to compile again, Jooq will fetch 9 tables, and generate theirs TableImpl.

  4. now I can un-comment the DAO, and compile again, finally everything will success. (Apparently, It's not an option to compile a project for three times).

If I change to QueryDSL (using apt-maven-plugin), it will success in the first time. Seems like QueryDSL first create Q-class and then compile the other code, but Jooq only generate code depends on a fully success compile, which is impossible. just like a dead-lock.

My pom.xml:

            <plugin>
                <groupId>com.mysema.maven</groupId>
                <artifactId>apt-maven-plugin</artifactId>
                <version>1.1.3</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>process</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>target/generated-sources/java</outputDirectory>
                            <processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
                        </configuration>
                    </execution>
                </executions>
            </plugin>



            <plugin>
                <groupId>org.jooq</groupId>
                <artifactId>jooq-codegen-maven</artifactId>
                <version>${jooq.version}</version>

                <executions>
                    <execution>
                        <id>jooq-codegen</id>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                    </execution>
                </executions>

                <configuration>
                    <generator>
                        <database>
                            <name>org.jooq.meta.extensions.jpa.JPADatabase</name>
                            <inputSchema>PUBLIC</inputSchema>
                            <outputSchemaToDefault>true</outputSchemaToDefault>
                            
                            <properties> 
                                <property>
                                    <key>packages</key>
                                    <value>com.mypack.business</value>
                                </property>
 
                                <property>
                                    <key>useAttributeConverters</key>
                                    <value>true</value>
                                </property> 
                                <property>
                                    <key>unqualifiedSchema</key>
                                    <value>none</value>
                                </property>
                            </properties>
                        </database>
                        <target>
                            <packageName>com.mypack.business.repository.entity.jooq</packageName>
                            <directory>target/generated-sources/java</directory>
                        </target>
                    </generator>
                </configuration>
            </plugin>

So how can I make Jooq compile success for just one time?

Or, if it's difficult, can I spread pojo and DAO (including jooq codegen) into two project to solve it?


Solution

  • This is documented in the manual page of the JPADatabase. The JPADatabase doesn't use any annotation processing hook into the compilation process and generate your TableImpl. Instead, it uses previously compiled entities and runs Hibernate DDL generation on them. That means, you have to compile your entities first, and only then generate your jOOQ code, and only then compile your DAO. See the manual section on how to organise your dependencies:

                    +-------------------+
                    | Your JPA entities |
                    +-------------------+
                         ^         ^
              depends on |         | depends on
                         |         |
      +---------------------+   +---------------------+
      | jOOQ codegen plugin |   | Your application    |
      +---------------------+   +---------------------+
                         |         |
               generates |         | depends on
                         v         v
                 +-------------------------+
                 | jOOQ generated classes  |
                 +-------------------------+
    

    If you think about what happens behind the scenes, that appears to be a much cleaner approach than relying on annotation processing's various caveats and limitations caused by the fact that they have to happen during compilation.

    JPA entities are self-contained, and can be designed as a re-usable libraries for various other componnents. DAOs will depend on both JPA entities and/or jOOQ code, and other lower level stuff.