Looking back through the spec and the implementation details, it looks like
your latter interpretation is accurate.  At least from our implementation
viewpoint.  Outside of your experiments earlier, are you hearing from
customers that they are expecting the alternative interpretation?  Pinaki
was our expert with the Criteria API, so maybe he can provide more
background.

Thanks, Kevin

On Tue, Nov 8, 2016 at 5:04 PM, Mark Struberg <[email protected]>
wrote:

> After digging through the spec I'm not really sure whether this is even
> intentional.
>
> There are an explicit CriteriaBuilder#parameter methods. And if I use
> those then I get a perfectly fine
> "SELECT * FROM Department d WHERE d.name <> :x"
>
> Using setParameter("x", "bla") on the resulting TypedQuery yields perfect
> results.
>
> Happy to get some feedback!
>
> LieGrue,
> strub
>
>
>
>
> > On Tuesday, 8 November 2016, 23:30, Mark Struberg
> <[email protected]> wrote:
> > > Hi folks!
> >
> >
> > I think I found something smelly in our CriteriaQuery implementation.
> This is
> > related to OPENJPA-2668.
> >
> > Currently EntityManager#createQuery(CriteriaQuery cq) returns the fully
> > 'interpreted' string. And no parameters.
> >
> >
> > Example:
> >
> > CriteriaBuilder cb = em.getCriteriaBuilder();
> > CriteriaQuery<Department> q = cb.createQuery(Department.class);
> > Root<Department> book = q.from(Department.class);
> > q.where(cb.notEqual(book.get(Department_.name), "X"));
> > TypedQuery<Department> dept = em.createQuery(q);
> >
> >
> > This creates the TypedQuery with
> >
> > "SELECT * FROM Department d WHERE d.name <> 'X'"
> > And no parameter at all.
> >
> > But imo it should use
> > "SELECT * FROM Department d WHERE d.name <> ?"
> > with dept.getParameters() returning a Parameter with pos 1 and value
> > 'X'.
> > Wdyt?
> >
> >
> > Not quite sure though how it should behave in Expression.In.
> >
> >
> > CriteriaBuilder cb = em.getCriteriaBuilder();
> > CriteriaQuery<Customer> cq = this.cb.createQuery(Customer.class);
> > Root<Customer> customerRoot = cq.from(Customer.class);
> > cq.select(customerRoot)
> >              .where(cb.and(cb.equal(customerRoot.get(Customer_.
> lastName),
> > "Hans"),
> >
> > customerRoot.get(Customer_.name).in(Arrays.asList("A", "B",
> > "C"))));
> > String queryString = cq.toString();
> >
> >
> > Currently this returns
> >
> > "SELECT c FROM Customer c WHERE c.lastname = 'Hans' and c.name IN
> > ('A','B', 'C')"
> >
> > This is imo wrong.
> > But the question is whether it should return
> >
> > "SELECT c FROM Customer c WHERE c.lastname = ? and c.name IN (?)"
> >   or whether it already need to 'extend' the parameters
> >
> > "SELECT c FROM Customer c WHERE c.lastname = ? and c.name IN (?, ?,
> > ?)"
> >
> > Of course the later is what will be used for the prepared statement.
> > But the one parameter version might be easier to reuse with different
> > parameters?
> >
> > LieGrue,
> > strub
> >
>

Reply via email to