My idea was to allow a parameter to be a collection valued parameter
only in two cases
1. When used with the IN predicate
2. When used as last argument for a function and the parameter is a
var-arg parameter
That way the query can be validated upfront when knowing the registered
functions and their argument types, but it's obviously not clear from
just looking at the query string if a parameter is multi-valued or not.
If you want to make the semantics independent of the functions, then you
must introduce a syntax of course. I was just trying to suggest
something that is mostly compatible to the way it is right now.
Am 10.09.2016 um 16:10 schrieb Steve Ebersole:
WRT the "double caches"... yes there will be a few caches.
I'm not understanding what that has to do with defining a clear
semantic for a particular language element.
----
Look, to me this whole thing boils down to the fact that JPA defines
specific/limited support for this "collection valued input parameter"
language element. It does that btw because the ideal in language
design is to be able to wholly understand the semantic of a part of a
query based only on the syntax[1]. Further, JPA requires that we
handle a user binding a "collection valued input parameter" directly
through #setParameter.
So all told we have a set of overloaded methods (#setParameterList)
that are not really providing any value[2], but that are needed
because that provides the only indication we ever get that a
particular parameter placeholder identifies a "collection valued input
parameter" rather than a"single valued input parameter". For all the
reasons discussed[1], thats not the ideal language design because it
is not deterministic from the grammar.
Think of it this way... It would be nice++ to be able to say "this
parameter is allowing multi-valued input" or "this parameter is
expecting single-valued input (multi-value input disallowed)", right?
Its the whole reason JPA defines its grammar (BNF) the way it does, so
that we can properly validate the incoming parameter input. Today I
can do something like this:
s.createQuery("from Zoo z where z.name <
http://z.name> = :name" )
.setParameterList("name",new String[] {"San Antonio
Zoo","Waco Zoo" } )
.list();
That is a completely "valid" query. Its not going to return anything
useful, but syntactically it is valid because we cannot understand the
proper semantic. And we do not understand the proper semantic
because it is not deterministic wrt the grammar/syntax. Ideally you'd
want to throw an exception back to the user here as soon as they try
to call #setParameterList for a parameter we conceptually *know*
should not accept "collection valued input parameters"
----
[1] This gets into language and grammar design, but there are a few
reasons you want to encode as much semantic understanding into the
syntax as possible. There are a few reasons for this; the 2 main ones
for us:
1. validation - again, here if I understand that a parameter
placeholder should or should-not allow "collection valued input
parameter" I can apply better validation up front (the sooner this
type of feedback can happen the better)
2. performance - anytime the query itself is not clear as to its
semantic there is going to be a performance aspect to resolving
that unclarity.
[2] I can see the argument of #setParameterList providing a better API
for passing the multi-value bind value in terms of type signature.
But ultimately IMO both "collection valued input parameter" and
"single valued input parameter" ought to be stored in one structure.
Today they are not, can't because we need to know that
#setParameterList was called instead of #setParameter because that is
our only understanding of the semantic - that this is a "collection
valued input parameter", not a"single valued input parameter".