[hibernate-dev] 6.0 - HQL literals

Christian Beikov christian.beikov at gmail.com
Thu Jan 9 02:28:16 EST 2020


Am 08.01.2020 um 20:21 schrieb Steve Ebersole:
> On Wed, Jan 8, 2020 at 9:22 AM Christian Beikov 
> <christian.beikov at gmail.com <mailto:christian.beikov at gmail.com>> wrote:
>
>
>     This is about JPA Criteria whereas I was referring to how a
>     literal in
>     HQL ends up in the SQL. I agree that with JPA Criteria things are
>     different as the API for parameters in queries is not very neat. A
>     flag
>     for controlling how literals should be rendered in for JPA Criteria
>     sounds ok, but ultimately, a literal should be just that, a literal.
>
>
> Well no - its about how literals defined in ORM queries should be 
> handled in JDBC.  The HQL / criteria distinction is not important here.
>
> We'll agree to disagree that query literals should always be rendered 
> as SQL literals.

I got that you are concerned with the security aspect and think that the 
DBMS optimizer will not be able to build significantly better plans than 
with parameters. Is there any other reason why you prefer rendering 
literals as JDBC parameter by default?

Since string literals in JPQL/HQL are defined syntactically like in SQL, 
the security part sounds managable to me as other (currently existing) 
literals are non-problematic due to their nature i.e. being numeric or 
strictly typed such the representation can't interferre with the SQL 
they are embedded into.

The performance part is for me actually very critical. I attached a few 
links[1][2][3][4] to articles that cover this topic. Essentially, the 
difference in execution plans come from wrong row count estimates 
because of wrong selectivity. When using parameters, DBMS do a few 
tricks to overcome the problems of unknown selectivity due to a missing 
value. Oracle is pretty good at that AFAIU, but the behavior is 
configurable and we might run in an environment where it isn't configure 
how we'd expect it to be.

PostgreSQL seems to use a generic plan(with wrong selectivity estimates) 
after the 5th execution and other DBMS probably have similar problems. 
In general, using literals is imporant when there are only a few values 
or when the row distribution is non-uniform. The problem gets big when a 
query has lots of joins that multiply to the wrong estimates, leading to 
e.g. full table scans rather than index scans.

[1] 
http://davetechnotes.blogspot.com/2009/02/literal-vs-bind-variables-bind-variable.html

[2] 
https://medium.com/@FranckPachot/postgresql-bind-variable-peeking-fb4be4942252

[3] 
https://blog.jooq.org/2018/04/12/why-sql-bind-variables-are-important-for-performance/

[4] 
https://blog.jooq.org/2017/05/30/when-to-use-bind-values-and-when-to-use-inline-values-in-sql/



More information about the hibernate-dev mailing list