Adnotacja @ElementCollection czy @OneToMany?
Adnotacja @ElementCollection czy @OneToMany?
Zacznijmy od adnotacji @ElementCollection. Adnotacja ta to jedna z adnotacji z pakietu:
import javax.persistence.*;
która pozwala szybko zmapować kolekcje danych.
Utwórzmy tabelę:
create table subject ( id integer generated by default as identity, name varchar(255), subject_id integer, primary key (id) )
Oraz mapowanie klasy jako obiektu wbudowanego z użyciem adnotacji @Embeddable:
@Embeddable @Data @AllArgsConstructor @NoArgsConstructor public class Subject { private String name; }
Klasa obiektu wbudowanego musi być oznaczona adnotacją @Embeddable. Nie oznacza się jej jako encji, tym bardziej nie określa się dla niej tabeli w bazie danych ani identyfikatora.
- Klasa Teacher – każdy nauczyciel może prowadzić wiele przedmiotów:
@Entity @Data @NoArgsConstructor public class Teacher { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) int id; String name; public Teacher(String name) { this.name = name; } @ElementCollection @CollectionTable( name = "subject",joinColumns = @JoinColumn(name="id") ) Set<Subject> subjects = new HashSet<>(); }
Oznaczenie kolekcji obiektów subjects adnotacjami:
@ElementCollection @CollectionTable(name = "subject",joinColumns = @JoinColumn(name="id"))
pozwala szybko i w prosty sposób zmapować tabelę Subject na kolekcje obiektów typu Subject. Klasa Subject to nie jest jednak encja zarządzana przez Hibernate co oznacza, że nie ma możliwości operowania na jej obiektach tak jak w przypadku klas oznaczonych adnotacją @Entity. Operacje bazodanowe na obiektach klasy Subject możliwe są tylko i wyłącznie z użyciem klasy nadrzędnej – Teacher która jest encją zarządzana przez Hibernate.
Relacja @OneToMany wyglądałaby następująco:
- Klasa Teacher:
@Entity @Data @NoArgsConstructor public class Teacher { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) int id; String name; public Teacher(String name) { this.name = name; } @OneToMany(mappedBy = "teacher") Set<Subject> subjects = new HashSet<>(); }
- klasa Subject:
@Entity @Data @NoArgsConstructor public class Subject { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) int id; String name; @ManyToOne @JoinColumn(name="subject_id", nullable=false) Teacher teacher; }
Takie mapowanie pozwala zarządzać encją Subject w sposób niezależny od encji nadrzędnej.
Leave a comment