Hi,
i would like to suggest or start a(-nother) open discussion about data access in cases where i do not want to explicitly define JPQL statements, but instead act on a slightly higher abstraction level.
I know that the platform relies (and advocates) heavily on JPQL (and even puts it up to the UI with the datasource concept) and oftentimes i really appreciate that.
Nevertheless, i think there are use cases where it is not necessary to know about the details of a JPQL query.
There are different options for something like this (not meaning that the libs can be used (although sometimes the could, but more as an example of the approach they took). I will just pick a few here, that i’m aware of (which does not mean that this is a representative choice):
GORM - gorm.grails.org
Basically there are two major options in GORM for doing queries.
- dynamic finders. This option basically looks like this Book.findByTitleLike(“Harry Pot%”). Dynamic Finders allow super easy access for easy queries, more medium advanced queries they are mostly not used.
- where queries. Where queries are similar to dynamic finders but they allow more complex expressions. Here’s an example:
Person.where {
(lastName != "Simpson" && firstName != "Fred") || (firstName == "Bart" && age > 9)
}
Where queries have the advantage that compared to a JPQL (or HQL in this case as well as hibernates criteria API) they allow
compile time checks (like dynamic finders as well).
Spring Data JPA - projects.spring.io/spring-data-jpa
In the Spring Data world normally a interface has to be created to defines access methods. This interface
will gets translated dynamically to JPQL through Spring, so there does not need to be an implementation of this interface.
It is the same like the configuration interfaces that can be defined in CUBA for receiving app properties.
public interface SimpleUserRepository extends CrudRepository<User, Long> {
List<User> findByLastname(String lastname);
@Query("select u from User u where u.firstname = :firstname")
List<User> findByFirstname(String firstname);
}
JPA Named Queries - JPA Named Queries
In the JPA world there is the possibility to define named queries. Those queries are just names for JPQL expression, meaning that there are no compile time checks e.g. Here’s an example:
@Entity
@NamedQueries({
@NamedQuery(name="Country.findAll",
query="SELECT c FROM Country c"),
@NamedQuery(name="Country.findByName",
query="SELECT c FROM Country c WHERE c.name = :name"),
})
public class Country {
//...
}
CUBA predefined JPQL REST queries
In the REST API (v2) there is the possibility to do actually the exact same thing as JPA named queries + the knowledge of the views.
Those are just names as well, not type checked etc. But they are adjustable at runtime, which is interesting in some cases.
Here’s an example:
<queries>
<query name="carByVin" entity="ref$Car" view="carEdit">
<jpql><![CDATA[select c from ref$Car c where c.vin = :vin]]></jpql>
<params>
<param name="vin" type="java.lang.String"/>
</params>
</query>
</queries>
I don’t want to favor any kind of framework here, because basically to some degree they have all the same features.
In Django and Rails are very similar to the grails approach (or the other way around actually :)).
The whole point is just to list different options, because i want to show the different abstraction levels. When looking at options for something like this in CUBA i always thing of it with support for the security layer (otherwise i could just most of the libraries straight away - without CUBA support).
As there are more of these requests (like myself a fairly long time ago or a request about named queries) i would like to start a conversation about the topic and what we can do about it.
What to you think about these thoughts?
Bye
Mario