Enterprise Java Development@TOPIC@
Uni-directional
Only one side ("owner") knows of the relationship
Uses the @ManyToMany annotation
Defines mapping to database
Must use @JoinTable
Bi-directional
Both classes know of the relationship
One side required to be owning side and maps relation to the database
Uses the @ManyToMany annotation
Must use @JoinTable
Changes here change the database
One side required to be inverse and names the other entity's property
@ManyToMany(mappedBy="owning-property")
Changes here do *not* change database
Figure 62.3. Many-to-Many Uni-directional Database Schema
create table ORMREL_WANTED ( +----> id bigint generated by default as identity, | primary key (id) | ) | create table ORMREL_WANTED_MEDIA ( `----- ORMREL_WANTED_id bigint not null, +----- media_MEDIA_ID bigint not null | ) | create table ORMREL_MEDIA ( `----> MEDIA_ID bigint generated by default as identity, title varchar(255), primary key (MEDIA_ID) ) alter table ORMREL_WANTED_MEDIA add constraint FKEE528304A70D4E48 foreign key (media_MEDIA_ID) references ORMREL_MEDIA alter table ORMREL_WANTED_MEDIA add constraint FKEE52830486AFC6B6 foreign key (ORMREL_WANTED_id) references ORMREL_WANTED
Figure 62.4. Many-to-Many Uni-directional Database Java Mapping
@Entity @Table(name="ORMREL_WANTED")
public class WantList {
@Id @GeneratedValue
private long id;
@ManyToMany
@JoinTable(name="ORMREL_WANTED_MEDIA") //define table, let columns use default names
+----- private Collection<Media> media = new ArrayList<Media>();
| ...
| @Entity @Table(name="ORMREL_MEDIA")
| public class Media {
| @Id @GeneratedValue @Column(name="MEDIA_ID")
`----> private long id;
private String title;
Figure 62.5. Many-to-Many Uni-directional Example Usage
for(WantList w: wantLists) {
for(Media m: media) {
//we can only navigate this in one direction
w.getMedia().add(m);
logger.info("added media({}) to want list ({})", m.getId(), w.getId());
}
}
Figure 62.6. Many-to-Many Uni-directional Database Output
-added media(1) to want list (1) -added media(2) to want list (1) -added media(1) to want list (2) -added media(2) to want list (2) -added media(1) to want list (3) -added media(2) to want list (3) Hibernate: insert into ORMREL_WANTED_MEDIA (ORMREL_WANTED_id, media_MEDIA_ID) values (?, ?) ...
Rows added to join table rather than updating entity class tables with foreign key
Figure 62.7. Many-to-Many Bi-directional Database Schema
create table ORMREL_AUTHOR ( +-----> id bigint generated by default as identity, | name varchar(255), | primary key (id) | ) | create table ORMREL_AUTHOR_MEDIA ( `----- LINK_AUTHOR_ID bigint not null, +----- LINK_MEDIA_ID bigint not null | ) | create table ORMREL_MEDIA ( `----> MEDIA_ID bigint generated by default as identity, title varchar(255), primary key (MEDIA_ID) ) alter table ORMREL_AUTHOR_MEDIA add constraint FKA0D2B4E09B01C6F2 foreign key (LINK_MEDIA_ID) references ORMREL_MEDIA alter table ORMREL_AUTHOR_MEDIA add constraint FKA0D2B4E089FFE922 foreign key (LINK_AUTHOR_ID) references ORMREL_AUTHOR
Figure 62.8. Many-to-Many Bi-directional Database Java Mapping
@Entity @Table(name="ORMREL_AUTHOR")
public class Author {
@Id @GeneratedValue
private long id;
private String name;
@ManyToMany
@JoinTable(name="ORMREL_AUTHOR_MEDIA", //defines the link table
//defines the column in the link table for author FK
joinColumns={@JoinColumn(name="LINK_AUTHOR_ID")},
//defines the column in the link table for the media FK
inverseJoinColumns={@JoinColumn(name="LINK_MEDIA_ID")})
+--> @OrderBy("title DESC") //order the list returned from database
+----- private List<Media> media = new ArrayList<Media>();
| |
| | @Entity @Table(name="ORMREL_MEDIA")
| | public class Media {
| | @Id @GeneratedValue @Column(name="MEDIA_ID")
| | private long id;
| | private String title;
| `---- @ManyToMany(mappedBy="media") //names property in Author that points to us
`-----> private Collection<Author> authors = new ArrayList<Author>();
Figure 62.9. Many-to-Many Bi-directional Example Usage
for(Author a: authors) {
for(Media m: media) {
a.getMedia().add(m);
logger.info("added media({}) to author ({})", m.getId(), a.getId());
m.getAuthors().add(a);
logger.info("added author({}) to media ({})", a.getId(), m.getId());
}
}
Owning and inverse sides now both need to be set
Figure 62.10. Many-to-Many Bi-directional Database Output
-added media(3) to author (1) -added author(1) to media (3) ... -added media(5) to author (5) -added author(5) to media (5) Hibernate: insert into ORMREL_AUTHOR_MEDIA (LINK_AUTHOR_ID, LINK_MEDIA_ID) values (?, ?) ... Hibernate: insert into ORMREL_AUTHOR_MEDIA (LINK_AUTHOR_ID, LINK_MEDIA_ID) values (?, ?)