Why is query dsl entity path limited to four levels? - java

Im currently using the maven apt plugin to generate the EntityPath base classes.
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>maven-apt-plugin</artifactId>
<version>1.0.4</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<outputDirectory>target/generated-sources/java</outputDirectory>
<processor>com.mysema.query.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>${querydsl.version}</version>
</dependency>
<dependency>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<classifier>apt</classifier>
<version>${querydsl.version}</version>
</dependency>
</dependencies>
</plugin>
this generates the desired Q classes and it is helpful in building predicates for queries. However i noticed that i always get a null pointer exception whenever i exceed four levels ie:
QFoo.foo.x.y.z
where Z is of type QZ; a generated EntityPath as well.
is this a limitation of the QueryDSL?

Yes, this is a limitation of Querydsl. Since the normal path initialization uses final fields a limit needs to be used. Luckily path initialization can be customized in many ways http://www.querydsl.com/static/querydsl/3.5.0/reference/html/ch03s03.html#d0e2181

Related

Failed to execute goal org.apache.cxf:cxf-codegen-plugin:3.5.4:wsdl2java

I'm trying to generate the code from WSDL file with CXF in Maven. Currently using Java 19 which I'd like to keep.
My plugin is configured with:
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>3.5.4</version>
<executions>
<execution>
<phase>generate-sources</phase>
<configuration>
<sourceRoot>${project.build.directory}/generated/cxf</sourceRoot>
<wsdlOptions>
<wsdlOption>
<wsdl>${basedir}/src/main/wsdl/sample.wsdl</wsdl>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>4.0.1</version>
</dependency>
<!--dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>4.0.1</version>
</dependency-->
</dependencies>
</plugin>
And always get error:
[ERROR] Failed to execute goal org.apache.cxf:cxf-codegen-plugin:3.5.4:wsdl2java (default) on project customsx: Execution default of goal org.apache.cxf:cxf-codegen-plugin:3.5.4:wsdl2java failed: A required class was missing while executing org.apache.cxf:cxf-codegen-plugin:3.5.4:wsdl2java: javax/xml/bind/annotation/adapters/HexBinaryAdapter
I'm familiar with the bind-api removal in Java 11, and always was able to solve usual JAXB troubles using jakarta libs.
In this particular case the error seems to come from wsdl2java itself. If I do not set the jakarta dependencies the error is exclusively on javax.xml.bind.annotation as expected. If I add the dependency the error is now on HexBinaryAdapter, which I can't seem able to solve.
Any ideas ?

Combining Querydsl-jpa and querydsl-sql and code generation

Here is the thing:
I have been using querydsl-jpa in my projects and code generation has never been a problem. I use this plugin in maven:
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>maven-apt-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/generated-sources</outputDirectory>
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>
Now, I need to also use querydsl-sql and apparently, I can't use the Q-generated classes created by com.querydsl.apt.jpa.JPAAnnotationProcessor. Here is the plugin in maven:
<plugin>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-maven-plugin</artifactId>
<version>4.2.1</version>
<executions>
<execution>
<goals>
<goal>export</goal>
</goals>
</execution>
</executions>
<configuration>
<jdbcDriver>com.mysql.cj.jdbc.Driver</jdbcDriver>
<jdbcUrl>jdbc:mysql://localhost:3306/mydatabase</jdbcUrl>
<jdbcUser>root</jdbcUser>
<jdbcPassword></jdbcPassword>
<packageName>com.myproject.domain</packageName>
<targetFolder>${project.basedir}/target/generated-sources/java</targetFolder>
</configuration>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.13</version>
</dependency>
</dependencies>
</plugin>
THE CHALLENGE
The second plugin above generates Q-classes for all schemas in my DBMS (MySql) whereas I have specified the schema to generate Q-classes from.
How do I specify the username, password and jdbcUrl from a file since I don't want to store sensitive information in the git repository.
Here are my solutions:
For challenge one, I haven't found a solution per se but some sort of workaround. I created a user in my DBMS (MySql) that has privileges on the single schema that I am interested in. That way, the user won't be able to generate Q-classes for other schemas. So problem one "solved".
Though I still believe that in the plugin one should be able to specify the schema to be generated. Interestingly enough <schemaPattern></schemaPattern> as suggested by #Rober Bain which is also in the querydsl-sql documentation does not work.
For challenge two, first you need to create a properties files say dev.properties with the needed content
jdbc-url=jdbc:mysql://localhost:3306/myschema?nullNamePatternMatchesAll=true
jdbc-user=my_user
jdbc-password=my_password
Then, include the following properties-maven-plugin
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0-alpha-2</version>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>read-project-properties</goal>
</goals>
<configuration>
<files>
<file>dev.properties</file> // Reference to properties file
</files>
</configuration>
</execution>
</executions>
</plugin>
... and in your query-dsl plugin ...
<plugin>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-maven-plugin</artifactId>
<version>4.2.1</version>
<executions>
<execution>
<goals>
<goal>export</goal>
</goals>
</execution>
</executions>
<configuration>
<jdbcDriver>com.mysql.jdbc.Driver</jdbcDriver>
<jdbcUrl>${jdbc-url}</jdbcUrl>
<jdbcUser>${jdbc-user}</jdbcUser>
<jdbcPassword>${jdbc-password}</jdbcPassword>
<packageName>com.myproject.domain</packageName>
<targetFolder>${project.basedir}/target/generated-sources/java</targetFolder>
</configuration>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.6</version>
</dependency>
</dependencies>
</plugin>
Check out this link for more info Read pom.xml configurations from properties file
Since the above link is down, use Wayback Online to see the original web page.
or
Here is a snapshot of the content
and a continuation
Use schemaPattern within the configuration element: "a schema name pattern in LIKE pattern form; must match the schema name as it is stored in the database, multiple can be separated by comma (default: null)" from the querydsl docs.
While the doesn't do exactly what you're asking for, I believe it's the standard way of solving this problem. Use encrypted data in a Maven pom.

com.mysema.querydsl querydsl-apt plugin does not generate QueryDSL classes

We had configured the generation of QueryDSL in our project using the maven plugin:
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>1.1.0</version>
<configuration>
<processor>com.mysema.query.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
<dependencies>
<dependency>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>${querydsl.version}</version>
</dependency>
</dependencies>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/java</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
At some point, we made changes in our project, and the generation process begin to fail with this error:
cannot find symbol import xxx.xxxx.xxxx.domain.QContact;
After some investigation, this problem is caused by a class that has been entirely commented.
For example:
//package xxx.xxxx.xxxxx;
////
//public class Test {
////
//}
If you put a class like this in your domain package, the generation process fails.
Well, on the other hand, this kind of classes wouldn't have to exist in your project.

Generate QueryDsl Q Classes From Package

How do I generate QueryDsl Q-Classes by only specifying a package name?
Given the source classes reside in my target/generated-sources folder since they are the product of other build plugins (WSDLs, XSDs, etc.)
I have tried using the following plugins, but can't find the right configuration:
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-maven-plugin</artifactId>
<version>2.9.0</version>
<executions>
<phase>generate-sources</phase>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources</outputDirectory>
<processor>${com.mysema.query.apt.ProcessorClass}</processor>
</configuration>
</executions>
and:
<groupId>com.mysema.maven</groupId>
<artifactId>maven-apt-plugin</artifactId>
<version>1.0.4</version>
What I'd like to do is something like this:
<configuration>
<packageName>com.my.package</packageName>
<sourceFolder>target/generated-sources</sourceFolder>
<targetFolder>target/generated-sources/querydsl</targetFolder>
</configuration>
...which would generate the classes:
com.my.package.QFoo.java
com.my.package.QBar.java
Since there's no common JPA or JDO annotation, and I don't have have access to the source files, I haven't been able to use any of the com.mysema.query.apt.*Processors for the maven-apt-plugin's <processor>.
EDIT 1: added full maven-apt-plugin configuration.
EDIT 2:
- I was able to get the maven-apt-plugin to work sporadically via the maven command line, but not Eclipse/STS by extending AbstractQuerydslProcessor to look for #XmlType-annotated classes. Double code-generation is admittedly not an ideal solution.
The answer is to generate the Q-classes using the strategy Timo outlined here: https://github.com/mysema/querydsl/issues/196
In my module's package-info.java:
#QueryEntities({ com.remote.module.Foo.class,
com.remote.module.Bar.class })
package com.my.local.module.querydsl;
import com.mysema.query.annotations.QueryEntities;
The plugin execution in the Maven POM:
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<executions>
<execution>
<id>apt-maven-plugin-remote-module-QuerydslAnnotationProcessor</id>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources</outputDirectory>
<showWarnings>true</showWarnings>
<!-- genereate Q-classes specified in package-info.java -->
<processor>com.mysema.query.apt.QuerydslAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
</dependency>
</dependencies>
</plugin>

Eclipse, QueryDSL and Spring Roo working together?

I'm trying to set up a maven-based SpringRoo project with QueryDSL in Eclipse and cannot seem to get the generator working when I have Roo enabled. If I create a plain project, and populate my pom.xml with the necessary querydsl plugins/dependencies, my metamodel classes are automatically generated.
However, if I switch to a basic ROO project, and add the necessary querydsl plugins/dependencies, then no metamodel classes are generated.
These are the additions I've put in my pom.xml:
<!-- Querydsl -->
<dependency>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-core</artifactId>
<version>${querydsl.version}</version>
</dependency>
<dependency>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>${querydsl.version}</version>
</dependency>
<dependency>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<version>${querydsl.version}</version>
</dependency>
<plugin>
<!-- Requires mysema m2e plugin (http://ilx.github.com/m2e-querydsl/repository/0.0.5/) -->
<groupId>com.mysema.maven</groupId>
<artifactId>maven-apt-plugin</artifactId>
<version>1.0.4</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<configuration>
<logOnlyOnError>true</logOnlyOnError>
<outputDirectory>target/generated-sources/apt</outputDirectory>
<processor>com.mysema.query.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>${querydsl.version}</version>
</dependency>
<dependency>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<classifier>apt</classifier>
<version>${querydsl.version}</version>
</dependency>
</dependencies>
</plugin>
<!-- right now this seems needed -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>target/generated-sources/apt</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
I am using Eclipse 3.7, m2e 1.2, Java 6. I also have the mysema m2e plugin installed from http://ilx.github.com/m2e-querydsl/repository/0.0.5/.
Does anyone have a working configuration with Roo and QueryDSL that works? If so, can you share your pom.xml please?
Thanks,
Eric
com.mysema.query.apt.jpa.JPAAnnotationProcessor needs javax.persistence.Entity annotated Java files. If you use other annotations or add the Entity annotation at runtime, no classes will be generated.
See this chapter of the Querydsl reference docs for classloader based code generation as an alternative to APT http://www.querydsl.com/static/querydsl/2.8.2/reference/html/ch03s02.html
For some reason that I do not understand, I needed to add a spring-tx dependency to my pom.xml. Once that was in place, the metamodel classes were automatically generated. There was a caveat however, I needed to manually annotate my entities with #Entity and not rely on Roo to annotate it via aspects. Finally, updating my plugin to 1.0.7 removed the need to use maven-build-helper.
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- QueryDSL plugin -->
<plugin>
<!-- Requires mysema m2e plugin (http://ilx.github.com/m2e-querydsl/repository/0.0.5/) -->
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>1.0.7</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/apt</outputDirectory>
<processor>com.mysema.query.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>${querydsl.version}</version>
</dependency>
<dependency>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<classifier>apt</classifier>
<version>${querydsl.version}</version>
</dependency>
</dependencies>
</plugin>
Sample Java Bean:
#RooJavaBean
#RooToString
#RooJpaEntity
#Entity
public class Client {
#Temporal(TemporalType.TIMESTAMP)
#DateTimeFormat(style = "M-")
private Date created_on;
private String name;
}
There's old discussion about this topic, where Ken Rimple states that " I had trouble getting anything to work on the QueryDSL generators with the pre-built ITDs. Since the actual class doesn't have an #Entity on it (until the AspectJ compiler comes in and adds it) when the QueryDSL is generating code, it doesn't see them as entities."
http://www.manning-sandbox.com/thread.jspa?threadID=51012&tstart=15
To me this seems to be something one could try to tweak by changing order in which maven is using plugins (lifecycle phases).

Categories