Страницы

Поиск по вопросам

вторник, 24 декабря 2019 г.

Примеры записи аннотаций @OneToMany @OneToOne @ManyToMany @ManyToOne [Hibernate]

#hibernate #jpa #аннотации


Интересуют как создавать сущности с аннотациями:  


@OneToOne  
@OneToMany   
@ManyToOne  
@ManyToMany


Так же вариации с bidirectional и unidirectional

Так же было бы неплохо добавить объяснений типо Cascade.**
    


Ответы

Ответ 1



Данный ответ будет модифицироваться по мере получения нужных знаний Update 11.09.2019: Вместо List<> используйте где возможно Set<> ...иначе при работе с join fetch (кастомном hql-запросе) у вас будет выпадать ошибка: org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple Bags: Более подробно об ошибке написано тут Не используйте CascadeType.ALL Если кратко - лучше использовать только с @OneToOne, т.к. при использовании со множественными связями могут удалиться ненужные записи из бд. Данный момент подробно описан в данном источнике Все ниже приведенные примеры я подробно показываю в своем мини-проекте, который можно скачать с GitHub О каскадировании можно почитать тут Project Lombok В моих ответах я использую аннотации Project Lombok: - @Data - Аннотация, которая добавляет в ваш проект Getters/Setters, Equals, ToString, HashCode - @AllArgsConstructor - Конструктор, содержащий все глобальные переменные, записанные в данном классе - @NoArgsConstructor - Пустой конструктор. Если мы не хотим в самом конструкторе прописывать данные, а использовать Setter - @ToString(exclude - "НазваниеПеременной") - При работе с bidirectional у нас будет зацикливаться объекты. Чтобы этого не допустить - надо от них избавиться Другие аннотации Project Lombok Установка плагина Project Lombok в IntelliJ и Eclipse @OneToOne Вариант unidirectional: От Пользователя к Покупателю, но не от Покупателя к Пользователю User.java: @Data @AllArgsConstructor @NoArgsConstructor @Entity @Table(name = "users") public class User { @Id @GeneratedValue private long id; @Column private String username; //Some code @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JoinColumn(name = "customer_id", unique = true) private Customer customer; } Customer.java @Data @Builder @AllArgsConstructor @NoArgsConstructor @Entity @Table(name = "customer") public class Customer { @Id @GeneratedValue @Column(name = "country_id") private long id; //Some code @Column(name = "customer_name") private String customerName; } Вариант bidirectional: От Пользователя к Покупателю и от Покупателя к Пользователю @OneToMany Вариант unidirectional: У Поста есть несколько Комментариев, но нам не нужно от Комментария искать Пост Post.java: @Data @AllArgsConstructor @NoArgsConstructor @Entity @Table(name = "post") public class Post { @Id @GeneratedValue @Column(name = "post_id") private Long id; @Column private String postHeader; @OneToMany( cascade = CascadeType.ALL, orphanRemoval = true ) private List comments = new ArrayList<>(); public void addComment(Comment comment) { comments.add(comment); } public void removeComment(Comment comment) { comments.remove(comment); } } Comment.java: @Data @AllArgsConstructor @NoArgsConstructor @Entity @Table(name = "comment") public class Comment { @Id @GeneratedValue @Column(name = "postcom_id") private Long id; @Column private String text; } Вариант bidirectional: *Профессор на курсе может узнавать информацию о студентах, в тоже самое время студенты могут узнавать информацию о Профессоре * Professor.java: @Data @NoArgsConstructor @AllArgsConstructor @Entity @ToString(exclude = "students") @Table(name = "professor") public class Professor { @Id @GeneratedValue @Column(name = "professor_id") private Long id; @Column private String name; @OneToMany( mappedBy = "professor", cascade = CascadeType.ALL, orphanRemoval = true ) List students = new ArrayList<>(); /* As you see we need to do something like "recursion" below */ public void addStudent(Student student) { students.add(student); student.setProfessor(this); } public void removeStudent(Student student) { students.remove(student); student.setProfessor(null); } } Student.java @Data @NoArgsConstructor @AllArgsConstructor @Entity @ToString(exclude = "professor") @Table(name = "student") public class Student { @Id @GeneratedValue @Column(name = "student_id") private Long id; @Column private String name; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name="professor_id") private Professor professor; } @ManyToOne @ManyToMany Вариант unidirectional: Пользователь может иметь несколько Ролей, Роль могут быть присвоина нескольким Пользователям User.java @Entity public class User { @Id @GeneratedValue @Column(name = "user_id") private long id; ... @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id")) private List roles = new ArrayList<>(); public void addRoles(Role role) { roles.add(role); } public void removeRoles(Role role) { roles.remove(role); } } Role.java @Entity public class Role { @Id @GeneratedValue @Column(name = "role_id") private int id; @Column(name = "role") private String role; } Вариант bidirectional: Трейдер может торговать на нескольких Биржах, Биржы могут посещаться несколькими Трейдерами Trader.java: @Data @AllArgsConstructor @NoArgsConstructor @Entity @ToString(exclude = "stockmarkets") @Table(name = "trader") public class Trader { @Id @GeneratedValue @Column(name = "trader_id") private Long id; @Column(name = "trader_name") private String traderName; @ManyToMany(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE }) @JoinTable(name = "TRADER_STOCKMARKET", joinColumns = { @JoinColumn(name = "trader_id") }, inverseJoinColumns = { @JoinColumn(name = "stockmarket_id") }) private List stockmarkets = new ArrayList<>(); /* We need to add methods below to make everything work correctly */ public void addStockmarket(Stockmarket stockmarket) { stockmarkets.add(stockmarket); stockmarket.getTraders().add(this); } public void removeStockmarket(Stockmarket stockmarket) { stockmarkets.remove(stockmarket); stockmarket.getTraders().remove(this); } } Stockmarket.java @Data @AllArgsConstructor @NoArgsConstructor @Entity @ToString(exclude = "traders") @Table(name = "stockmarket") public class Stockmarket{ @Id @GeneratedValue @Column(name = "stockmarket_id") private Long id; @Column(name = "stockmarket_name") private String stockmarketName; @ManyToMany(mappedBy="stockmarkets") private List traders = new ArrayList<>(); /* We need to add methods below to make everything work correctly */ public void addTrader(Trader trader) { traders.add(trader); trader.getStockmarkets().add(this); } public void removeTrader(Trader trader) { traders.remove(trader); trader.getStockmarkets().remove(this); } }

Комментариев нет:

Отправить комментарий