var q = from o in db.Orders from c in db.Customers
where o.Quality == «200» && (o.CustomerID == c.CustomerID)
select new { o.DueDate, c.CompanyName, c.ItemID, c.ItemName };
В JPA есть такая прикольная штука - по сущностям генерятся всякие доп-классы с константами-названиями полей. В связке с Criteria API получаем полностью статически типизированный ORM. По-моему годно. В Hibernate такого не видел.
А HQL, JPQL это всё неудобная гадость. SQL и то удобней.
Это не только для динамически формируемых запросов, а ещё и для будущих изменений схемы (меняется схема - с необходимостью нужно переделывать все места, которые затронуты данным изменением - компилятор просто не соберёт места, написанные под старую схему), портируемости (возможно подкладывание какой-нибудь не RDBMS) итп. Реальность, конечно, сложнее, но, в целом, код более контролируемый. Да, я помню, что code coverage в идеале должен быть over 146% :)
Для валидации того же JPQL можно использовать @NamedQuery, конечно, не во время компиляции, а во время деплоя но и Criteria API требуют пересборку классов.
В любом случае эта проблема удачно решается через автоматизированное интеграционное тестирование в обоих случаях.