JavaEEのJPAで、同じCriteriaなのに違うSQLが生成されることがある

JPAで、同じCriteriaなのに違うSQLが生成されることがあって、毎回違う結果を返してくるのでハマりました。
EclipseLink 2.3.2です。


同じテーブルをさすRootを2つ作ると、場合によって解釈が違うという感じです。


つまり

  CriteriaQuery cq = em.createQuery(TDUser.class);
  Root<TDUser> root1 = cq.from(TDUser.class);
  Root<TDUser> root2 = cq.from(TDUser.class);
  cq.where(cb.equal(root1.get("id").as(Long.class), 10L);
  cq.orderBy(cb.asc(root2.get("id"));
  em.createQuery(cq).getResultList();

のように、whereとorderByで別のRootオブジェクトを使うと、場合によって次の2通りのSQLが生成されることがあります。

select ID, NAME 
from td_user 
where ID=10 
order by ID

または

select t0.ID, t0.NAME 
from td_user t0, td_user t1 
where t1.ID=10 
order by t0.ID

です。


場合によってというか、だいたい2/3の確率で後者です。
もちろん、後者の場合にはwhere句が効かないので、全件取得になってしまいます。


一箇所で記述するときにはRootをちゃんと使いまわすので問題になりにくいですが、便利メソッドを作ってCriteria構築処理が分割されると陥りやすいと思います。
Criteriaは、クエリーを部分的に共通化できるというのが強みなのに、それをやってしまうとハマるというのは非常に困った挙動です。
常にどちらか決まってればいいのだけど。
すごくハマりました。