[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"question-hibernate-mapping-svyazey-mezhdu-sushchnostyami":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},754,"mapping-svyazey-mezhdu-sushchnostyami",19,"hibernate","Hibernate","🐻","Маппинг связей между сущностями","Hibernate поддерживает четыре типа связей, соответствующих отношениям в реляционной модели.\n\n### @ManyToOne \u002F @OneToMany — самая частая связь\n\n\u003Cdetails>\n\u003Csummary>Пример двунаправленной связи\u003C\u002Fsummary>\n\n```java\n\u002F\u002F Сторона \"многие\" — владелец связи (содержит FK)\n@Entity\npublic class Order {\n    @Id\n    @GeneratedValue(strategy = GenerationType.IDENTITY)\n    private Long id;\n\n    @ManyToOne(fetch = FetchType.LAZY)\n    @JoinColumn(name = \"user_id\", nullable = false)\n    private User user;\n}\n\n\u002F\u002F Сторона \"один\" — обратная сторона\n@Entity\npublic class User {\n    @Id\n    @GeneratedValue(strategy = GenerationType.IDENTITY)\n    private Long id;\n\n    @OneToMany(mappedBy = \"user\", cascade = CascadeType.ALL, orphanRemoval = true)\n    private List\u003COrder> orders = new ArrayList\u003C>();\n\n    \u002F\u002F Вспомогательные методы для синхронизации обеих сторон\n    public void addOrder(Order order) {\n        orders.add(order);\n        order.setUser(this);\n    }\n\n    public void removeOrder(Order order) {\n        orders.remove(order);\n        order.setUser(null);\n    }\n}\n```\n\n\u003C\u002Fdetails>\n\n### @OneToOne\n\n```java\n@Entity\npublic class User {\n    @OneToOne(mappedBy = \"user\", cascade = CascadeType.ALL,\n              fetch = FetchType.LAZY, optional = false)\n    private UserProfile profile;\n}\n\n@Entity\npublic class UserProfile {\n    @Id\n    private Long id; \u002F\u002F общий PK с User\n\n    @OneToOne(fetch = FetchType.LAZY)\n    @MapsId \u002F\u002F PK UserProfile = FK на User\n    @JoinColumn(name = \"id\")\n    private User user;\n}\n```\n\n### @ManyToMany\n\n```java\n@Entity\npublic class Student {\n    @ManyToMany\n    @JoinTable(\n        name = \"student_course\",\n        joinColumns = @JoinColumn(name = \"student_id\"),\n        inverseJoinColumns = @JoinColumn(name = \"course_id\"))\n    private Set\u003CCourse> courses = new HashSet\u003C>();\n}\n\n@Entity\npublic class Course {\n    @ManyToMany(mappedBy = \"courses\")\n    private Set\u003CStudent> students = new HashSet\u003C>();\n}\n```\n\n### Важное\n\n- `mappedBy` — указывает обратную (не владеющую) сторону связи; FK хранится на стороне без mappedBy\n- Всегда используйте `FetchType.LAZY` для `@OneToMany` и `@ManyToMany`\n- `@ManyToOne` по умолчанию EAGER — явно указывайте LAZY\n- Для `@ManyToMany` предпочитайте Set вместо List — производительнее при операциях удаления\n- Синхронизируйте обе стороны связи (helper-методы addOrder, removeOrder)\n\n### Частые ошибки\n\n- Не указывать mappedBy — Hibernate создаст промежуточную таблицу вместо использования FK\n- Использовать List в `@ManyToMany` — при удалении Hibernate удалит все записи из join-таблицы и вставит заново; Set удаляет точечно\n- EAGER для коллекций — загрузка всех связанных сущностей сразу ведёт к N+1 и OutOfMemoryError\n- Двунаправленная связь без синхронизации — если не обновить обе стороны, in-memory модель не совпадает с БД\n- `@OneToOne` с LAZY — LAZY для `@OneToOne` на стороне без FK не работает без bytecode enhancement (Hibernate должен знать, null ли связь, что требует запроса)\n\n### Как используется в 2026\n\n- `@ManyToOne(fetch = LAZY)` + JOIN FETCH — золотой стандарт\n- `@ManyToMany` часто заменяется промежуточной сущностью (`@Entity StudentCourse`) для добавления атрибутов связи\n- Hibernate 6 улучшил работу с `@OneToOne` LAZY через bytecode enhancement\n\n> **На собеседовании:** начните с `@ManyToOne`\u002F`@OneToMany` как самой частой связи. Объясните mappedBy — кто владелец связи и где FK. Ключевое правило — всегда LAZY. Интервьюер может спросить про подводные камни `@ManyToMany` — ответ: используйте Set, а лучше промежуточную сущность.","","middle",[15,16,17,18,7],"relationships","mapping","fetch","jpa",[],null,{"title":22,"description":23,"ogTitle":24,"ogDescription":25,"keywords":26,"schemaAnswer":36,"featuredSnippetReady":37},"Маппинг связей между сущностями в Hibernate — Gymterview","Связи JPA: @ManyToOne, @OneToMany, @OneToOne, @ManyToMany. mappedBy, FetchType.LAZY, синхронизация сторон, Set vs List для ManyToMany.","Маппинг связей: @ManyToOne, @OneToMany, @OneToOne, @ManyToMany — Gymterview","Четыре типа связей в JPA\u002FHibernate. mappedBy, владелец связи, LAZY загрузка, Set vs List. Примеры кода и частые ошибки.",[27,28,29,30,31,32,33,34,8,35],"ManyToOne","OneToMany","OneToOne","ManyToMany","mappedBy","JoinColumn","FetchType","LAZY","JPA","Hibernate поддерживает 4 типа связей: @ManyToOne\u002F@OneToMany (самая частая, FK на стороне Many), @OneToOne (общий PK через @MapsId), @ManyToMany (join-таблица, предпочитайте Set). mappedBy указывает обратную сторону. Правила: всегда LAZY, Set для ManyToMany, синхронизация обеих сторон helper-методами. Золотой стандарт: @ManyToOne(fetch = LAZY) + JOIN FETCH.",true]