Relazioni molti a molti con JPA

Oggi ho imparato a fare le relazioni molti a molti con JPA. E' abbastanza semplice. Ve lo spiego con un esempio. Abbiamo due entità
  1. Book
  2. Author
Un libro puo' essere stato scritto da uno o piu' autori. Un autore può aver scritto uno o piu' libri. Per rendere la relazione basta usare @ManyToMany, nel nostro caso: Book.java:
public class Book implements Serializable {
private Long id;
private List<Author> authors = new ArrayList<Author>();
protected String title;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="id")
public Long getId() {
    return id;
}

@ManyToMany(cascade=CascadeType.PERSIST)
public List<Author> getAuthors() {
    return authors;
}

public String getTitle() {
    return title;
}

public void setTitle(String title) {
    this.title = title;
}

public void setId(Long id) {
    this.id = id;
}

public void setAuthors(List<Author> authors) {
    this.authors = authors;
}

}
Author.java
@Entity
@Table(name="Autores")
public class Author implements Serializable {
private Long id;
protected String name;
private List<Book> books;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="id")
public Long getId() {
    return id;
}

@ManyToMany(mappedBy = "authors")
public List<Book> getBooks() {
    return books;
}

public String getName() {
    return name;
}

public void setId(Long id) {
    this.id = id;
}

public void setName(String name) {
    this.name = name;
}

public void setBooks(List<Book> books) {
    this.books = books;
}

}
Esempio di utilizzo:
EntityManager em = ...

Author author1 = new Author();
Author author2 = new Author();
Author author3 = new Author();

author1.setName("Pippo");
author1.setName("Pluto");
author1.setName("Paperino");

Book book1 = new Book();
book1.setTitle("Vivere a topolinia");
book1.getAuthors().add(author1);
book1.getAuthors().add(author2);
book1.getAuthors().add(author3);

Book book2 = new Book();
book2.setTitle("Vivere a Paperopoli");
book2.getAuthors().add(author3);

em.persist(book1);
em.persist(book2);
Nota sul mapping Le relazioni molti a molti non possono essere espresse direttamente sui database relazionali, è infatti necessario introdurre una tabella che faccia da ponte. Nei casi semplici è possibile ignorare questi dettagli perché sono gestiti dal provider JPA. Però nel caso la struttura del database sia già definita e necessario istruire JPA in modo che utilizzi la tabella ponte giusta. Questo si fa usando l'annotazione @JoinTable. Per esempio nel caso la tabella ponte sia definita come:
CREATE TABLE "LIBROS_AUTORES" (
  "libros_id" BIGINT NOT NULL,
  "autores_id" BIGINT NOT NULL);
Useremo annoteremo getAuthors nel seguente modo:
 @JoinTable(
    name="LIBROS_AUTORES",
    joinColumns=@JoinColumn(name="libros_id", referencedColumnName="id"),
    inverseJoinColumns=@JoinColumn(name="autores_id",referencedColumnName="id")
)
public List<Author> getAuthors() {
    return authors;
}