Как работать с нативными SQL запросами после включения логирования
Что проверяют
Умеете ли вы увидеть, какой SQL на самом деле уходит в базу из JPA, и что делать, когда запрос Hibernate вас не устраивает. Логирование здесь инструмент диагностики: включили, увидели N+1 или тяжёлый запрос, решили, переписывать ли его на нативный. Следом спрашивают, как логировать значения параметров и чем это опасно на проде.
Как отвечать
Сначала настройка логов в Spring Boot 3 с Hibernate 6:
logging.level.org.hibernate.SQL=DEBUG: текст запросов через логгер. Флагspring.jpa.show-sql=trueпишет в stdout мимо логгера и для реальной работы хуже;logging.level.org.hibernate.orm.jdbc.bind=TRACE: значения параметров. В Hibernate 5 для этого была категорияorg.hibernate.type.descriptor.sql.BasicBinder;hibernate.format_sqlиhibernate.generate_statistics: читаемое форматирование и статистика числа запросов за сессию;- datasource-proxy или p6spy: перехват на уровне JDBC, видно всё, включая
JdbcTemplate, с подставленными параметрами и временем выполнения.
Нативный запрос выполняется через @Query(value = "...", nativeQuery = true) или entityManager.createNativeQuery(sql, User.class). Без класса результата придёт список Object[], а не сущности. Для DTO подходят интерфейсные проекции Spring Data или @SqlResultSetMapping. Параметры только через привязку: спецификация JPA для нативных запросов гарантирует позиционные ?1, именованные :id поддерживает Hibernate.
Помните про контекст сохранения. UPDATE через нативный запрос идёт мимо него, и уже загруженные сущности остаются со старыми значениями. В Spring Data для этого есть @Modifying(flushAutomatically = true, clearAutomatically = true). План нативного запроса смотрите через EXPLAIN ANALYZE в самой базе.
Где спотыкаются
Склеивают SQL конкатенацией строк, раз уж запрос нативный. Это прямой путь к SQL-инъекции.
Оставляют TRACE на привязку параметров на проде. Логи раздуваются, а в них попадают персональные данные и токены.
Не сбрасывают контекст после нативного UPDATE и потом ищут, почему в той же транзакции сущность показывает старое значение.