Coder Social home page Coder Social logo

blazebit / blaze-persistence Goto Github PK

View Code? Open in Web Editor NEW
687.0 23.0 85.0 36.75 MB

Rich Criteria API for JPA providers

Home Page: https://persistence.blazebit.com

License: Apache License 2.0

Shell 0.13% Java 99.09% CSS 0.40% HTML 0.04% ANTLR 0.21% JavaScript 0.03% FreeMarker 0.08% Batchfile 0.01%
java jpa sql criteria-api cte

blaze-persistence's People

Contributors

andyjefferson avatar aniket-singla avatar beikov avatar benjaminbloomteq avatar berndartmueller avatar bramhaag avatar danelowe avatar david-kubecka avatar dependabot[bot] avatar eugenmayer avatar fk-currenxie avatar gsmet avatar jlleitschuh avatar jwgmeligmeyling avatar mobe91 avatar pilpin avatar postremus avatar pvncoder avatar riteshka avatar slyoldfox avatar sullrich84 avatar tapegram avatar thjanssen avatar tom-mayer avatar vladmihalcea avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

blaze-persistence's Issues

Make CriteriaBuilder context dependent

Create a class CriteriaFactory which has a context and can produce criteria builders.
This can be used to bind configuration originating from extensions to that context.

For PaginatedCriteriaBuilder: throw exception for subqueries in order by that reference collection fields of the surrounding query

This requirement resulted from issue #38
An exception is required in this scenario because this is the only scenario in which the id query can result in multiple result set rows with the same root entity id. This is because we have to include the subquery in the select clause if it is used in the order by. Furthermore, if the subquery references a collection from the surrounding query it will cause the final result set to contain multiple rows for the same root entity.

Support expressions around subqueries in where, select, having

We currently have where().
Replace this with whereSubquery(String expression), whereSubquery(String subqueryAlias, String expression) and whereSubquery().

Replace the subquery alias in the expression with the subquery expression. The expression can be transformed right after the subquery builder terminates.

Implement OUTER() function in expressions

The OUTER() function is used within a subquery to retrieve the join alias for a given absolute path from the surrounding query.
Extract an ExpressionFactory interface with the createSimpleExpression method. The normal implementation should not support the OUTER() function. Only the new second implementation for subqueries should support the function.

Test expression literals

JPQL defines several literals, check if the parser can properly handle them and which are support in hibernate because I think hibernate had problems with some literals.

Array access does not work as expected

Given following JPQ query:

SELECT d.id, contacts.name FROM Document d LEFT JOIN d.contacts contacts WITH KEY(contacts) = 1

Hibernate generates the following SQL query:

select
    document0_.id as col_0_0_,
    person2_.name as col_1_0_ 
from
        Document document0_ 
left outer join
        contacts contacts1_ 
            on document0_.id=contacts1_.Document_id 
left outer join
        Person person2_ 
            on contacts1_.contacts_id=person2_.id 
            and (
                contacts1_.contacts_KEY=1
            )

The first left outer join is performed because d.contacts uses a collection table. Hence, if one document has assigned two contacts this single join yields two rows for this document on the left side. Now, when the Person columns are joined we receive NULLs for the contact with KEY != 1.

Evaluate getQueryString performance and maybe implement caching

Currently we always generate a fresh query when we call getQueryString. If the performance is bad, we could think about caching the query string by name.
A CriteriaBuilderFactory could offer a method

from(String queryName, EntityManager em, Class entityClass, String alias)

The queryName could act as a cache key.

COUNT(*) syntax not allowed in JPQL

COUNT(*) is not allowed in JPQL, but Hibernate supports it. We should maybe switch to COUNT(rootAlias.id) which is what we actually want I guess.

Restructure EntityView Extension

Currently EntityViewManagers have to be created by calling EntityViewManagerProvider.from(EntityManager). CriteriaBuilders are created via Criteria.from(EntityManager, Class, String).

In the future we could provide an extension, that looks for EntityManager beans, and creates beans for EntityViewManagers and CriteriaBuilders so that those instances can be injected.

Maybe we also need to restructure how we can create object builders.

Implement Case When

We have already prototyped the case when API, now it needs to be implemented and some more tests have to be added.

Maybe remove QueryBuilder.select(java.lang.Class)

ObjectBuilders now need the JPA Metamodel and therefore we can not create them as we did before in the EntityViewExtension.
Either remove the method and auto-registration or introduce a possibility to make the persistence unit available to the extension.

Introduce flag that allows the generation of on clauses as where clauses

Hibernate currently only allows the usage of parameters, constants and the join alias in the with-clause of a join. As a workaround we could introduce a flag that allows the generation of with-clauses as where-clause.
Where clauses should look as follows:
OUTER JOIN relation ON condition
should result in
WHERE (relation.id IS NULL OR condition)

The NULL-check is only required for OUTER-Joins (i.e. all joins except INNER JOIN).

Add checks for invalid fetch joins

In JPA it is invalid to do join fetches when selecting something different than the root entity. Add checks to the criteria implementation so we don't get the error at querying time but before.

Rework entity view filters

Currently filters for mapping attributes can be applied with @MappingFilter which accepts a Filter class.
Hibernate filters inspired me and I want to do something similar.

Since providing a Filter class is much more typesafe we will leave it like that, but maybe the Filter interface will become an abstract class that offers some basic functionality. The @MappingFilter annotation will maybe get a name parameter which is defaulted to the attribute name. Also the constructor contract defined in the Filter interface should be removed if possible and replaced by setParameter and getParameter methods on the Filter interface/abstract class. We need getParameter for introspection in EntityViewSetting as we don't know parameter names in general but mostly assume there is only one parameter that can be set. We could maybe also introduce a convention that single parameter filters should use the parameter name 'value' or even add another method that accepts only an Object for exactly that case. That method would do what is currently provided by the constructor, but the contract would be much cleaner.

Since a method attribute or view type can then have multiple filters, but only one default, we have to add that in the metamodel.

To make filters more flexible we might also want to consider a possibility to add more than a single restriction. Currently a RestrictionBuilder is passed into the filter which is fine most of the time, but sometimes we might want to apply functions on the left hand side too, or even use more complex predicates.

This will finally make them as mighty as hibernate filters(I think), but more typesafe.

Support expressions around subqueries in order by for PaginatedCriteriaBuilder

We must support the following for id queries (we do not support this in the CriteriaBuilder or SubqueryBuilder):
e.g. selectSubquery("a").fromblabla.end().page(0,1).orderBySubquery("MAX(a)", true, false)

For the id query we must extract the wrapping expression for the order by clause and apply it to the corresponding select alias (which must correspond to a subquery). E.g we then have

SELECT id, MAX(SELECT bla FROM bla) AS a ORDER BY a

Access multiple elements of the same collection within a single query

Referring to InterfaceViewTest.testInterface(), following query is generated so far:

SELECT contacts, d.id, contacts, d.name FROM Document d LEFT JOIN d.contacts contacts WHERE KEY(contacts) = 1 AND KEY(contacts) = :contactPersonNumber ORDER BY d.id ASC NULLS LAST

This results in an empty result set if :contactPersonNumber != 1
Instead the query should be built like this:

SELECT contacts1, d.id, contacts2, d.name FROM Document d LEFT JOIN d.contacts contacts1 LEFT JOIN d.contacts contacts2 WHERE KEY(contacts1) = 1 OR KEY(contacts2) = :contactPersonNumber ORDER BY d.id ASC NULLS LAST

Joining a path multiple times

Currently we can only join a path like "doc.localized.name" once, but it is sometimes necessary to join it multiple times with different aliases.

This is especially necessary for queries that use indexed collections.

If for example one would want to select two distinct values from a map attribute with different keys, the resulting JPQL Query could look like:

"SELECT o1, o2, FROM SomeType s LEFT JOIN s.map o1 LEFT JOIN s.map o2 WHERE KEY(o1) = 1 AND KEY(o2) = 2"

Note that this query in contrast to the next one, only returns a result, if both there are objects for both keys 1 and 2.

"SELECT o1, o2, FROM SomeType s LEFT JOIN s.map o1 LEFT JOIN s.map o2 WHERE KEY(o1) = 1 OR KEY(o2) = 2"

This query would return null for o2 if there was no entry with key 2.

When enabling this feature, please consider the different use cases.

EntityViewSetting subview support

Currently the EntityViewSetting class can only handle direct attributes. It should also be able to handle subviews and collections.

AliasManager Hierarchy

We need a hierarchy because there could be two subqueries where equal aliases are allowed.

Implement expressions for subqueries in entity views

We will introduce methods in the criteria builder like xxxSubquery(String expression, String alias, ...) that make it possible to wrap an expression around a subquery. The MappingSubquery annotation and the metamodel have to be adapted. Also we have to adapt the current tuple element mappers for subqueries.

FROM statements are illegal in JPQL

Currently we generate hibernate specific FROM-statements which is wrong because that is not valid JPQL. We can easily generate something like SELECT rootAlias FROM...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.