Ответ
Использование нативных запросов (createNativeQuery) в JPA/Hibernate даёт прямой доступ к возможностям СУБД, но сопряжено с рядом рисков и сложностей:
1. Проблемы безопасности: SQL-инъекции
- Риск: Подстановка пользовательских данных напрямую в строку запроса.
- Решение: Всегда использовать параметризованные запросы.
// НЕПРАВИЛЬНО (уязвимо)
String sql = "SELECT * FROM users WHERE name = '" + userName + "'";
// ПРАВИЛЬНО (безопасно)
Query query = em.createNativeQuery("SELECT * FROM users WHERE name = ?1");
query.setParameter(1, userName);
// Или с именованными параметрами
Query query = em.createNativeQuery("SELECT * FROM users WHERE name = :name");
query.setParameter("name", userName);
2. Проблемы переносимости (Vendor Lock-in)
- Нативные запросы часто используют специфичный для СУБД синтаксис (например, оконные функции, типы данных), что привязывает приложение к конкретной базе данных.
3. Сложности с маппингом результатов
- Результат
Object[]неудобен для работы. - Маппинг на сущность (
@Entity) работает только если запрос возвращает все поля сущности в правильном порядке. - Решение: Использовать
@SqlResultSetMappingили конструктор DTO черезnewв JPQL-аналоге.
@SqlResultSetMapping(
name = "UserSummaryMapping",
classes = @ConstructorResult(
targetClass = UserSummaryDTO.class,
columns = {
@ColumnResult(name = "id", type = Long.class),
@ColumnResult(name = "name")
}
)
)
4. Отсутствие автоматической оптимизации и кэширования
- Hibernate не может оптимизировать нативный запрос, как это делается с JPQL/HQL (предотвращение N+1, выбор стратегии загрузки).
- Кэш запросов второго уровня по умолчанию не применяется к нативным запросам, требуется явная настройка.
5. Потеря абстракции и усложнение поддержки
- Запросы перестают быть независимыми от схемы БД. Изменения в таблицах требуют правки строковых констант в коде.
- Усложняется тестирование (может потребоваться конкретная СУБД).
Рекомендация: Используйте нативные запросы только для сложных аналитических запросов или оптимизаций, которые невозможно выразить через JPQL/Criteria API.