С какими ORM вы работали и как выполняли синхронные запросы
Что проверяют
Понимаете ли вы, что делает ORM за вас и какой ценой. Формулировка про «синхронные запросы» обычно проверяет, отдаёте ли вы себе отчёт: JPA блокирующая по своей природе, и никакой обёрткой запрос неблокирующим не становится.
Как отвечать
Про инструменты коротко: Hibernate как реализация JPA, поверх него Spring Data JPA; где нужен контроль над SQL, JdbcTemplate, MyBatis или jOOQ.
Про синхронный доступ по нарастанию сложности:
EntityManager.findпо идентификатору;- запрос на JPQL через
createQueryсsetParameter, для динамических фильтров Criteria API или спецификации; @Queryв репозитории и производные методы по имени;- нативный SQL, когда возможностей JPQL не хватает.
Обязательно про транзакции: границы ставятся на сервисном слое через @Transactional, для чтения добавляется readOnly = true, внутри транзакции работает кэш первого уровня, а изменения сущностей улетают в базу при сбросе контекста, а не в момент присваивания.
Сильная часть ответа это производительность: проблема N+1 и лечение через join fetch, @EntityGraph или пакетную загрузку; отдельная ловушка постраничной выборки вместе с join fetch по коллекции, когда Hibernate вытягивает всё в память; проекции в DTO вместо сущностей для чтения; LazyInitializationException при обращении к ленивому полю за пределами транзакции.
Где спотыкаются
Верят, что ORM оптимизирует сама, и ни разу не смотрели сгенерированный SQL. Логирование запросов и счётчики статистики Hibernate показывают, что на один вызов метода ушло не два запроса, а двести.
Отдают сущности прямо в ответ контроллера. Сериализатор дёргает ленивые связи, тянет полбазы, а на двусторонних ссылках уходит в бесконечную рекурсию.
Считают, что @Async или возврат CompletableFuture делает работу с базой асинхронной. Запрос всё равно блокирует поток, просто уже другой; настоящая неблокирующая работа это отдельный стек вроде R2DBC.