Asked Questions
Does anqu support JPA 2.2?
Yes. Two features of the JPA 2.2 spec have been introduced to anqu method: Repeatable annotations and the new getResultStream() method of Query/TypedQuery.
Switch on the generation of repeatable annotations (@NamedQuery and @NamedNativeQuery) in the preferences.
Additionally anqu can now create glue code that returns a stream of result objects.
Is there any problem with switching to JPA 2.2?
It depends. JPA 2.2 uses the streaming package (java.util.stream) which is part of Java since Java 8. So JPA 2.2 requires Java 8.
There is no problem for anqu. The already generated code will work.
Even the already generated dummy implementation of the Query/TypedQuery interface inside
the MockUtil classes will work.
How can that be? The dummy now needs to implement the new method getResultStream(). In JPA 2.2 the
new method has a default implementation, which delegates to getResultList(). So the dummy inherits this default implementation (at runtime).
Why should I use the code generation for getResultStream() instead of getResultList().stream()?
The method getResultList() fetches all results. The default implementation of getResultStream() will do the
same - but if there is a better implementation by a JPA provider, that could have real benefits. So if you
are using the streaming API for your results, please give your JPA provider the chance to speed you up by
calling getResultStream().
I cannot find anqu method in the Eclipse Marketplace Client. How dare you?
The client in Eclipse only finds open source products or products of their partners. anqu method
is free to use and has a rather non-restricting licence. However its source code is not available.
These limitations do not hold for the Marketplace web site. So please install per drag'n'drop of the
following image to your Eclipse installation (e.g. drag to the toolbar)
or visit anqu method in the Marketplace.
Parameters are missing or the generated method returns List<Object[]>. What's wrong?
There are at least two possible causes. First is that the query is not a valid JPA (2.0) query and
cannot be parsed. This does not mean that the query won't work. It depends on the special behaviour
of your JPA implementation. anqu method generates the most general solution in this case.
Here's a link to the JPA specification:
Eclipse Link JPA 2.0
Of course it is likely that anqu method has a bug. If you believe so, please report it via
this site.
How can I determine if a 'single result method' found nothing or null?
You cannot. The single result method is a convenience variation. It is kept simple and avoids
exceptions on purpose. Please create a 'execution method' and implement your logic yourself.
I want to re-use/re-configure the query. How can it be done?
The re-configuration of queries to run them more than once in a row with different parameters
is not directly supported by anqu method. Please use the 'Query Creation' variation and re-configure
the query yourself. Maybe think about re-creating the query instead of re-using it.
How can I set the LockMode?
First solution: Just as above use the 'Query Creation' variation in the context menu and get the query object and apply
your configuration. In this case you have to execute the query yourself.
Second solution: Generate the code for executing the query and add the LockMode assignment in the body.
You can also refactor the method to get the desired LockMode as parameter. Please remember that re-generating the method
will override your changes.
If you have generated test, you have to mock the behaviour of the setter method for the LockMode, too.
How do you know the persistence unit at compile time?
This is a Naq, a never asked question. Though it is really interesting since the answer is: I don't know anything about the
persistence unit. anqu is based on the assumption that everything is found on the classpath. And yes, you
can absolutely construct situations where the type resolution will break. That's one reason why you use it at own risk.
Why not just using a compiler hook?
The answer is the same as above. As you cannot be sure that the code generation finds the correct types, a fully automatic
implementation is not possible. With the generation of visible source code you can manually correct the errors in a simple
manner.
Where can I provide FirstResult and MaxResults?
Create a 'First/Max Method' - it will require both values.
What about Spring Data JPA or Apache DeltaSpike? Don't you know?
anqu is about generating glue code for named queries. Spring Data JPA and Apache DeltaSpike Data (reduced to the question
of named queries) also try to reduce coding overhead. Yet they still force you to write glue code into
the repository interface. And again that glue code has to fit to the existing query. Here anqu
helps to generate the method signature for the repository interface. So combine anqu and one of those tools!
Why do you prefer @NamedQuery to Criteria?
Do I? Both techniques suffer from the same problem: reflection. anqu method tries to
reduce the risks of reflection by encapsulation and tests. Criteria comes with a
meta model. But the problem is only solved if your meta model is up-to-date and you
do not use strings to refer to fields.
Named queries introduce logic to entity classes. Criteria can be defined everywhere.
Criteria is only validated at runtime while named queries are validated at deployment
time.
Named queries are quite handy if you know SQL. If you are querying a relational database
with Criteria without knowing SQL - well... Criteria has all mechanisms like
joins and such. It basically is SQL.
After writing this and visiting some pages on the usage of Criteria: At least for simple
queries I prefer @NamedQuery (with anqu method support) to Criteria due to the following
comparison on text to write:
Named query to write, then use anqu method:
@NamedQuery(name="findAllPets", query="SELECT p FROM Pet p")
Equivalent Criteria taken from Oracle's web site, method wrapped around:
public static List<Pet> findAllPets(EntityManager em) { CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<Pet> cq = cb.createQuery(Pet.class); Root<Pet> pet = cq.from(Pet.class); cq.select(pet); TypedQuery<Pet> q = em.createQuery(cq); return q.getResultList(); }
Do the generated tests verify the query?
No. Neither the query syntax nor its semantics are validated.
The tests only check that
the generated code still fits to the query. They also provide 100% code coverage for
the generated code. They provide 0% coverage for the query itself.
The query does what you have written. Please write test to check that what you have
written is what you meant to implement.
When the glue code is in the entity, should I extract a String constant for the query name?
Having various constants in an entity makes it less legible. You can use the generated tests
to check that glue code and query statement fit together as an alternative.
Does'nt having the glue code in the entity destroy the abstraction?
If you demand that an entity is just a description of the object oriented mapping - of course.
As for JPA, the entity also is the place to define named queries. They are part of the business logic.
Regarding this, glue code in the entity is a simple abstraction for the technical query execution code.