Open otaviojava opened 8 months ago
seems specific to JPA criteria
A pattern like this is something to consider post v1.0 when more is added to the static metamodel to better enable it.
A pattern like this is something to consider post v1.0 when more is added to the static metamodel to better enable it.
Agreed. This isn't something I would bite off for 1.0. I think really it's tricky to get right. (Speaking from hard experience here.)
By the way, since this issue is open, I just want to record for the future that @njr-11 has proposed something that I think is really nice, in some ways quite a lot nicer than a "full" criteria query API. The idea is to use the static metamodel to express "restrictions" which can be passed to a repository methods.
Conceptually, something like this:
repo.books(_Book.title.like("Jakarta Data%"),
_Book.publicationDate.between(pastDate, LocalDate.now()))
Or, if you need to combine this with ordering:
repo.books(where(_Book.title.like("Jakarta Data%"),
_Book.publicationDate.between(pastDate, LocalDate.now())),
by(_Book.title.ascIgnoreCase(),_Book.isbn.asc())))
[Don't focus on the details here, I know @njr-11 has thought about this longer than I have and surely has more-developed ideas about it.]
Of course, this is much less expressive than a real criteria API. But:
Now, on the other hand, it's also completely compatible with a full criteria API, it's not really in competition at all. The objects returned by like()
and between()
could be criteria expressions.
Anyway, I would love to have this, and I think users would stampede for something like it.
That is nice! IIMHO: it would be faster than the query language.
I wonder if it might be helpful to look at how go-jet approaches this?
I have a very, very simple real-life scenario here.
select * from Post
where
id in (select postId from PostTag where tagId in :tagIds) #if tagIds is empty, return empty result
and status in (:statuses). #if statuses is empty, ignore this filter
1、Is there any way to achieve repository more easily? 2、Is there any way to achieve PostQuery more semantic?
@Entity
@Table(name = "post")
public class PostEntity {
@Id
@UuidGenerator(style = TIME)
private String id;
private String status;
private OffsetDateTime createdAt;
...getter/setter
}
@Entity
@Table(name = "post_tag")
public class PostTag {
@Id
@UuidGenerator(style = TIME)
private String id;
private String postId;
private String tagId;
...getter/setter
}
public class PostQuery {
private final Set<String> tagIds;
private final Set<String> statuses;
...getter/setter
}
@Repository
public interface PostRepository extends CrudRepository<Post, String> {
@Nonnull
StatelessSession session();
default Page<Post> pageBy(PostQuery query, PageRequest page) {
if (query.getTagIds() == null || query.getTagIds().isEmpty()) {
return new PageRecord<>(request, Collections.emptyList(), 0L);
}
CriteriaDefinition<Post> cd = new CriteriaDefinition<>(session().getFactory(), Post.class,
"""
select * from Post
where id in (select postId from PostTag where tagId in :tagIds)
""") {{
var post = from(Post.class);
if(query.getStatuses() != null && !query.getStatuses().isEmpty()){
restrict(in(post.get(Post_.status), query.getStatuses()));
}
orderBy(desc(post.get(Post_.CREATED_AT)));
}};
int totalResults = session().createSelectionQuery(cd)
.setParameter("tagIds", query.getTagIds())
.getResultCount();
List<Post> results = session().createSelectionQuery(cd)
.setParameter("tagIds", query.getTagIds())
.setFirstResult((int) (page.page() - 1) * page.size())
.setMaxResults(page.size())
.getResultList();
return new PageRecord<>(page, results, totalResults);
}
}
@pipinet I believe you're looking for https://github.com/jakartaee/data/issues/829
As a ...
I need to be able to ...
Expanding upon the capabilities of the Jakarta Data Query Language (#458), this proposal introduces the Criteria feature to enable programmatically constructing queries within the Jakarta Data framework. The Criteria API provides developers with an object-oriented approach to building query criteria, offering greater flexibility and control over data retrieval operations.
Which enables me to ...
The primary goal of this proposal is to initiate a discussion and a vote regarding the inclusion of the Criteria feature in the Jakarta Data project.
Key Features:
Programmatic Query Construction: The Criteria API allows developers to programmatically build query criteria using a fluent and object-oriented interface, eliminating the need for raw queries.
Filtering and Logical Conditions: Developers can apply various filtration rules and logical conditions to the criteria query object, enabling precise data retrieval based on specific criteria.
Integration with Jakarta Data Query Language: The Criteria feature seamlessly integrates with the Jakarta Data Query Language, providing an additional method for constructing queries within the framework.
Integration with Metadata: Criteria queries can be combined with metadata-driven queries, offering developers multiple options for constructing queries based on their requirements.
Integration with Repository: Introducing a new interface,
CriteriaRepository,
that extends the existingPageableRepository,
and enables seamless integration of criteria-based queries with repository pattern implementations.Additional information
Example Usage:
Benefits:
Simplified Query Construction: The Criteria API simplifies query construction by providing a fluent and object-oriented interface, reducing the complexity of query writing.
Enhanced Flexibility: Developers have greater flexibility in defining query criteria programmatically, allowing for dynamic and adaptable data retrieval operations.
Integration with Metadata and Query Language: The Criteria feature seamlessly integrates with metadata-driven queries and the Jakarta Data Query Language, providing a comprehensive solution for data access within the Jakarta Data framework.
Repository Integration: The introduction of
CriteriaRepository
enables developers to leverage criteria-based queries within the repository pattern, promoting code organization and reusability.