[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"question-hibernate-chto-takoe-proektsii-i-dto-mapping":3},{"id":4,"slug":5,"topicId":6,"topicSlug":7,"topicName":8,"topicEmoji":9,"question":10,"answer":11,"codeLang":12,"codeSrc":12,"important":12,"commonMistakes":12,"modernUsage":12,"difficulty":13,"tags":14,"related":19,"progress":20,"seo":21},1043,"chto-takoe-proektsii-i-dto-mapping",19,"hibernate","Hibernate","🐻","Что такое проекции и DTO-маппинг?","Проекции позволяют загружать только нужные поля из БД, а не полные сущности. Это оптимизирует производительность и решает проблемы с LAZY-загрузкой и безопасностью (не отдавать лишние данные).\n\n### DTO через JPQL-конструктор\n\n```java\npublic record UserDto(String name, String email) {}\n\n@Query(\"SELECT new com.example.UserDto(u.name, u.email) FROM User u WHERE u.id = :id\")\nOptional\u003CUserDto> findUserDtoById(@Param(\"id\") Long id);\n\u002F\u002F SQL: SELECT u.name, u.email FROM users u WHERE u.id = ?\n```\n\n### Interface-based проекция (Spring Data)\n\n```java\npublic interface UserSummary {\n    String getName();\n    String getEmail();\n\n    @Value(\"#{target.name + ' \u003C' + target.email + '>'}\")\n    String getDisplayName(); \u002F\u002F вычисляемое поле (SpEL)\n}\n\npublic interface UserRepository extends JpaRepository\u003CUser, Long> {\n    List\u003CUserSummary> findByStatus(UserStatus status);\n    \u002F\u002F Spring Data автоматически загружает только name и email\n}\n```\n\n### Class-based проекция (DTO класс)\n\n```java\npublic record UserDto(String name, String email) {}\n\nList\u003CUserDto> findByStatus(UserStatus status);\n\u002F\u002F Spring Data маппит результат в DTO автоматически (по именам полей)\n```\n\n### Tuple (кортеж) — для ad-hoc запросов\n\n```java\nList\u003CTuple> results = entityManager.createQuery(\n    \"SELECT u.name AS name, COUNT(o) AS orderCount \" +\n    \"FROM User u LEFT JOIN u.orders o GROUP BY u.name\", Tuple.class)\n    .getResultList();\n\nresults.forEach(t -> System.out.println(\n    t.get(\"name\") + \": \" + t.get(\"orderCount\")));\n```\n\n### Важное\n\n- Проекции загружают только нужные столбцы → меньше трафика, памяти, нет LAZY-проблем\n- Interface-based проекции — удобны, но создают прокси (чуть медленнее)\n- Record DTO — оптимальный по производительности вариант\n- Проекции не отслеживаются Persistence Context → нет Dirty Checking\n\n### Частые ошибки\n\n- Загружать полную Entity для read-only отображения — лишний overhead: Dirty Checking, snapshot, L1 Cache\n- Смешивать проекции и Entity — проекция возвращает DTO, не managed Entity; изменения в DTO не попадут в БД\n- Сложные SpEL в interface-проекциях — сложнее для отладки и тестирования\n\n### Как используется в 2026\n\n- DTO-проекции — стандарт для REST API (разделение read\u002Fwrite модели — CQRS-lite)\n- Java Records идеально подходят для DTO — иммутабельные, компактные\n- Spring Data автоматически оптимизирует SELECT при использовании interface\u002Fclass проекций\n\n> **На собеседовании:** проекции — это способ загружать только нужные поля вместо полной Entity. Назовите три вида: JPQL-конструктор, interface-based, class-based (record). Объясните, почему проекции лучше для REST API: нет Dirty Checking overhead, нет LAZY-проблем, не отдаём лишние данные клиенту.","","middle",[15,16,17,7,18],"performance","jpa","projection","dto",[],null,{"title":22,"description":23,"ogTitle":24,"ogDescription":25,"keywords":26,"schemaAnswer":35,"featuredSnippetReady":36},"Проекции и DTO-маппинг в Hibernate\u002FSpring Data — Gymterview","Проекции загружают только нужные поля: JPQL-конструктор, interface-based, class-based (record), Tuple. Оптимизация производительности для REST API.","DTO-проекции в Spring Data JPA: 4 способа загружать только нужные поля — Gymterview","JPQL-конструктор, interface-based, class-based (record), Tuple. Проекции — стандарт для REST API: нет Dirty Checking, нет LAZY-проблем.",[27,28,29,30,31,32,33,8,34],"DTO","проекция","interface projection","record","Tuple","Spring Data","JPQL конструктор","JPA","Проекции загружают только нужные поля из БД вместо полных сущностей. 4 вида: JPQL-конструктор (SELECT new UserDto(...)), interface-based (Spring Data создаёт прокси), class-based (record DTO — оптимальный), Tuple (ad-hoc). Проекции не отслеживаются Persistence Context, нет Dirty Checking overhead, нет LAZY-проблем. Стандарт для REST API (CQRS-lite).",true]