[Use Case]: JDQL fragments
- Dominant language
- Java
- Stars
- 150
- Forks
- 37
- Avg merge
- 4d 4h
- Merged PRs (30d)
- 34
Description
### As a ...
- [ ] Application user/user of the configuration itself
- [X] API user (application developer)
- [ ] SPI user (container or runtime developer)
- [ ] Specification implementer
### I need to be able to ...
specify JDQL expressions or fragments of JDQL in annotations.
### Which enables me to ...
reduce the cognitive dissonance in moving between `@Find` and `@Query`.
### Additional information
So in thinking through:
- the nature of the`@By` annotation,
- the potential for us to grow a whole zoo of similar animals in future (`@Like`, `@IgnoreCase`, `@In`, etc), and
- also about my unexpected happiness with how well `@OrderBy("name")` works, and _unhappiness_ with how ugly `@OrderBy(vale="name",descending=true,ignoreCase=true)` looks.
I came to the realization that there's a general approach that makes `@Find` much more flexible, reduces the conceptual gap between `@Find` and `@Query`, solves the problem with `@OrderBy`, and makes the trip to the zoo unnecessary.
[Don't get scared. I'm not proposing to do any of this today, I'm just trying to understand what the future might look like.]
The idea is to have a smaller set of annotations which accept fragments of JDQL. So, for example:
```java
@Find
@OrderBy("lower(title) desc")
@OrderBy("isbn")
List booksByTitle(Type type, @Where("title like :pattern") String pattern);
```
which would be assembled to:
```java
@Query("where title like :pattern and type = :type order by lower(title) desc, isbn")
List booksByTitle(Type type, String pattern);
```
You might even be able subsume `@Where` into `@By`, since it's pretty easy to distinguish a scalar expression with no parameters from a conditional expression with a parameter. And you might allow `@OrderBy` to accept a list. So:
```java
@Find
@OrderBy("lower(title) desc, isbn")
List booksByTitle(Type type, @By("title like :pattern") String pattern);
```
Now, one might look at this particular example, and think _"but the `@Query` version is shorter and perhaps even more readable"_, and that's true because this is a sort-of "extreme" case in the sense that I have three annotations and only two parameters. But if I had four parameters and just one or two annotations, it would look more attractive.
But that's anyway not the point. The point is to reduce the pressure to add lots of special-purpose annotations, and save the developer from getting into the sort of edit war where they find themselves switching back and forth between `@Find` and `@Query`.
To reiterate: `@Where("title like :pattern")` is more verbose than `@Like`. But it covers _many_ more cases and is somehow, at least to my way of thinking, a much more elegant approach.
Note that the content of these annotations can still be checked at compile time. JDQL has a _very_ a simple expression language that's easy to parse in an annotation processor.
So we would have:
- `@By` accepting `scalar_expression`,
- `@OrderBy` accepting `orderby_item` or perhaps a whole list of them,
- `@Where` accepting `conditional_expression` except for logical operators, and
- possibly `@Select` accepting `select_list` or perhaps just a single select item.
By side effect, `@By("id(this)")` becomes the much more elegant way to write `@By(ID)`.
Everything here looks backward-compatible with what we have today! That said, we _could_ consider adopting this approach for `@OrderBy` in this release, if we have time. But it's definitely not critical.
Contributor guide
Research direction
Start by comparing the existing @Find, @Query, @By, @Where, @OrderBy, and possible @Select annotation behavior described in the issue. Clarify the proposed JDQL fragment syntax and compatibility requirements before identifying implementation entry points. Done would require an agreed design and corresponding implementation, validation, and tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- api
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100