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
>