Hibernate / JPA: вопросы с ответами

36 разобранных вопросов по теме «Hibernate / JPA». Каждый — с правильным ответом и пояснением.

  • В чём разница: Content-Type: json vs form-urlencoded vs multipart?

    application/json: JSON в body (REST API). application/x-www-form-urlencoded: пары key=value (формы логина). multipart/form-data: для загрузки файлов (binary + metadata).

  • Entity как ключ HashMap — что может пойти не так?

    Если equals/hashCode используют lazy-связи (ManyToOne, OneToMany) — при первом вызове hashCode загрузится N связанных сущностей (N+1). Хуже: если связи двусторонние — бесконечная рекурсия и StackOverflowError.

  • Hibernate vs JDBC — в чём разница?

    JDBC — низкий уровень, прямой SQL, ResultSet, ручной маппинг колонок в поля. Hibernate — поверх JDBC: сам генерирует обычный SQL и маппит результаты в объекты. Удобно для типового CRUD.

  • JdbcTemplate — когда уместен вместо Hibernate?

    Сложные аналитические запросы (оконные функции, CTE). Batch-операции (тысячи INSERT). Запросы, где ORM генерирует неоптимальный SQL. Миграция legacy-кода. Простые CRUD без сложных связей — везде, где нужен полный контроль над SQL.

  • В чём разница: JOOQ vs Hibernate?

    JOOQ: типизированный SQL, compile-time проверка запросов, нет dirty checking. Hibernate: ORM, lazy loading, кэширование. В Путешествиях используют оба — JOOQ для сложных запросов, Hibernate для CRUD.

  • В чём разница: JPA vs Hibernate?

    JPA — спецификация (набор интерфейсов и аннотаций). Hibernate — одна из её реализаций (наряду с EclipseLink, OpenJPA). EntityManager — JPA-интерфейс, Session — нативный Hibernate-интерфейс, расширяющий спецификацию.

  • В чём разница: Lazy vs Eager загрузка?

    Lazy — связь подгружается только при обращении (прокси). Eager — сразу в SELECT. Default для @OneToMany и @ManyToMany — Lazy, для @ManyToOne и @OneToOne — Eager.

  • N+1 в JPA — как диагностировать?

    Включить логи SQL (spring.jpa.show-sql=true), смотреть количество запросов на эндпоинт, использовать p6spy или Hibernate Statistics.

  • N+1 — детально?

    1 findAll() + N доп. запросов на lazy-коллекции при обращении к ним: 1000 заказов → 1001 SQL. Обнаружение: hibernate.generate_statistics=true, datasource-proxy. Решения: JOIN FETCH, @EntityGraph, @BatchSize(100), @Fetch(FetchMode.SUBSELECT).

  • Что такое N+1 проблема?

    1 findAll() + N доп. запросов на lazy-коллекции. Решения: JOIN FETCH, @EntityGraph, @BatchSize(100), DTO-проекция. EAGER — неправильный ответ.

  • Что такое N+1 проблема в Spring Data JPA?

    При fetch = LAZY на связи, при итерации по списку делается +1 запрос за каждую связанную сущность. Решения: JOIN FETCH, @EntityGraph, BatchSize.

  • В чём разница: Pessimistic vs optimistic locking?

    Pessimistic: SELECT ... FOR UPDATE блокирует строку. Optimistic: версия (@Version) — при commit проверяется, изменилась ли она.

  • В чём разница: @SpringBootTest vs @WebMvcTest vs @DataJpaTest?

    @SpringBootTest: поднимает ВЕСЬ контекст (медленно, для интеграционных/E2E). @WebMvcTest: только веб-слой (контроллеры + MockMvc, без БД). @DataJpaTest: только JPA-слой + встроенная БД, с откатом транзакций после каждого теста.

  • В чём разница DTO и Entity?

    Entity — связана с БД (@Entity). Может иметь связи (LazyInitializationException наружу!). DTO — независимый объект для передачи. Хорошая практика: НЕ возвращать Entity из REST-контроллеров, маппить в DTO, чтобы не тянуть ленивые связи вне сессии.

  • В чём разница JPA и Hibernate?

    JPA (Java Persistence API) — спецификация (интерфейсы и аннотации в пакете javax.persistence / jakarta.persistence). Hibernate — её конкретная реализация (как EclipseLink и OpenJPA), которая вдобавок предоставляет собственные расширения: HQL, кэш второго уровня и т.д.

  • Как решить N+1?

    (1) JPQL с JOIN FETCH: select o from Order o join fetch o.user. (2) @EntityGraph — атрибут на репозиторий-методе, говорит «подгрузить эти поля сразу». (3) Hibernate default_batch_fetch_size — группирует SELECT'ы по пачкам вместо запроса на каждую сущность.

  • Как сделать пагинацию?

    Метод принимает Pageable, возвращает Page или Slice. Spring Data сам добавит LIMIT/OFFSET.

  • Какие виды связей бывают?

    @OneToOne — один к одному (User ↔ Passport). @OneToMany / @ManyToOne — один ко многим / многие к одному (User → Orders). @ManyToMany — многие ко многим (Student ↔ Course, через промежуточную таблицу).

  • Какой Fetch type по умолчанию?

    Для коллекций (@OneToMany, @ManyToMany) — Lazy. Для скалярных связей (@OneToOne, @ManyToOne) — Eager. Eager по умолчанию для @ManyToOne — частая ловушка: при загрузке Order сразу подтянется User, что провоцирует проблему N+1.

  • Каскадные операции: что делает CascadeType.ALL?

    PERSIST + MERGE + REMOVE + REFRESH + DETACH. Опасность: CascadeType.REMOVE при OneToMany — удаление родителя удалит ВСЕХ детей. Если детей 10 000 — 10 000 DELETE запросов.

  • Что такое Кэши Hibernate?

    First-level: автоматический, привязан к Session. Гарантирует identity (один PK = один объект). Second-level: опциональный, общий на уровне SessionFactory (EhCache, Caffeine, Infinispan). Query cache: кэширует результаты JPQL-запросов и требует включённого second-level.

  • Что такое Оптимистичная блокировка?

    @Version (int/long/Timestamp). UPDATE ... WHERE version = ?. Если не совпала — OptimisticLockException. Подходит для low-contention (веб-приложения). Пессимистичная: @Lock(PESSIMISTIC_WRITE) → SELECT FOR UPDATE — блокирует строку.

  • Что такое Оптимистичная блокировка в JPA?

    Поле @Version (int/long/timestamp). При update Hibernate сравнивает версию — если не совпала, бросает OptimisticLockException.

  • Что такое Проблема N+1?

    При итерации по списку на каждую связанную сущность делается отдельный SELECT. Решения: JOIN FETCH, @EntityGraph, @BatchSize, @Fetch(FetchMode.SUBSELECT).

  • Разница между get() и load() в Hibernate?

    get() — сразу идёт в БД и возвращает null если не найдено. load() — возвращает прокси, БД дёргается только при обращении к полям; если нет записи — ObjectNotFoundException.

  • Разница между save(), persist(), merge(), update()?

    persist — для новых (JPA стандарт, не возвращает id). save — Hibernate-specific, возвращает id. merge — копирует detached в managed. update — прикрепляет detached.

  • Что такое Состояния сущности?

    Transient — new User(), Hibernate не знает. Persistent/Managed — связан с сессией, dirty checking автоматически синхронизирует изменения. Detached — сессия закрыта/detach, изменения сами в БД не уходят, нужен merge(). Removed — помечен на удаление. Всего четыре состояния.

  • Что такое Состояния сущности в Hibernate?

    Transient (новый объект, Hibernate не знает), Persistent/Managed (связан с сессией), Detached (был persistent, но сессия закрыта), Removed (помечен на удаление).

  • Чем отличается JpaRepository от CrudRepository?

    JpaRepository extends PagingAndSortingRepository extends CrudRepository. Добавляет flush(), saveAllAndFlush(), работу с List вместо Iterable, deleteAllInBatch.

  • Что лучше — Lazy или Eager?

    Lazy. Eager почти всегда плохо — Hibernate тянет лишнее, и часто это даёт N+1 в неожиданном месте. Правило: ставь Lazy везде, а конкретный JOIN FETCH делай в запросах, где данные действительно нужны.

  • Что такое DTO?

    Data Transfer Object — объект для передачи данных между слоями системы или между сервисами. Не содержит логики, только поля и геттеры/сеттеры. Часто используется как тело REST-запросов и ответов.

  • Что такое N+1?

    Загрузил список из N сущностей одним запросом. Потом в цикле обращаешься к их LAZY-связям — на каждую идёт отдельный SELECT. Итого 1 + N запросов. На 100 сущностях это 101 запрос — катастрофа для производительности.

  • Что такое ORM?

    Object-Relational Mapping — отображение объектов на таблицы БД: класс User → таблица users, поля → колонки, связи (@OneToMany) → JOIN'ы. Hibernate сам генерирует SQL, а разработчик работает с объектами.

  • Что такое POJO?

    Plain Old Java Object — обычный Java-класс без специальных требований (наследования от чего-то, реализации интерфейсов фреймворка). Просто поля + геттеры + сеттеры + конструктор.

  • Что такое Spring Data JPA?

    Удобная обёртка над JPA / Hibernate: создаёшь интерфейс-наследник JpaRepository — Spring сам генерирует реализацию. Query methods: по имени метода вроде findByEmail Spring сам собирает SQL-запрос, работая с @Entity-классами.

  • Что такое VO?

    Value Object — объект, который определяется ТОЛЬКО своими значениями (не identity). Например, Money(amount, currency) — два VO с одинаковыми полями равны. Иммутабельны, имеют equals/hashCode по содержимому.

новые гайды и свежие вопросы с собесов — первыми в Telegram Смотреть гайды Подписаться