JPA Named Queries vs Criteria API?
Существует ли эвристическая/лучшая практика/набор правил для решения между API критериев и NamedQuery?
Мои мысли до сих пор:
Именованные запросы, как правило, более читабельны. Запросы критериев более гибкие.
Оба предварительно скомпилированы. Я склонен полагаться на использование названных запросов как можно дольше, а затем перейти к критериям.
Но, может быть,
стремление "сгибать" запрос с использованием критериев API - это намек на субоптимальный дизайн (т.е. разделение проблем)?
Спасибо
Ответы
Ответ 1
Именованные запросы более оптимальны (они разобраны/подготовлены один раз). Критические запросы являются динамическими (они не прекомпилированы, хотя некоторые поставщики JPA, такие как EclipseLink, поддерживают кеш подготовки критериев).
Я бы использовал критерии только для динамических запросов.
Ответ 2
Критерии запросов являются хорошим выбором, когда запрос должен генерироваться динамически, например, из переменных и нескольких критериев поиска.
Для статических запросов JPQL гораздо читабельнее, и я предпочитаю использовать их, кроме критериев. Вы можете потерять некоторую безопасность, но модульные тесты должны сделать вас более уверенными.
Ответ 3
Другая точка зрения заключается в том, что, хотя запрос критериев не читается, он является типичным, поэтому предоставляет вам проверку типа времени компиляции. Если вы меняете базу данных в проектах, где есть много объектов и много запросов, очень полезно видеть во время компиляции, какие запросы поступили неправильно из-за изменений.
С другой стороны, я не уверен, что это более выгодно, чем простота JPQL
Ответ 4
Я действительно прошел через источник Hibernate (4.3.0-SNAPSHOT) и источник EclipseLink (2.5.0-SNAPSHOT) и просмотрел реализацию JPA в каждом.
EclipseLink явно не является потокобезопасным в том виде, который вы описываете. В частности, он пытается повторно пересчитывать соединения.
Выполнение спящего режима выглядит безопасным для меня. Я не уверен на 100%, но это похоже. Я бы сказал, что это не гарантируется в будущем, так как оно не указано.
Однако, я предупрежу вас, я не думаю, что вы получите много. Из того, что я ищу, большая часть компиляции запроса выполняется на этапе "createQuery", поэтому вы даже не получите много кэширования результатов.
Ответ 5
JPA также предоставляет способ создания статических запросов, как именованных запросов, с помощью аннотаций @NamedQuery и @NamedQueries. Считается хорошей практикой в JPA, когда это возможно, предпочитать именованные запросы по динамическим запросам. Из http://www.objectdb.com/java/jpa/query/api