Настройка связи Многие-ко-Многим в Hibernate приложении

Теперь настроим в нашем приложении связь Многие-ко-Многим.

Пусть теперь в нашем приложении будет еще одна новая таблица – "Издательство".

Эта таблица будет связана с ранее созданной таблицей "Книги автора".

Любая книжка может быть напечатана несколькими издательствами и любое издательство может печатать какие-угодно книги.

То есть связь многие книги ко многим издательствам.

Ясное дело, при удалении издательства из таблицы publisher не должны удаляться связанные с этим издательством книги в таблице author_books, поскольку эти книги могут быть связаны и с другими издательствами.

И наоборот тоже – удаление книги не должно приводить к удалению связанных с ней издательств.

Поэтому и в классе таблицы publisher и в классе таблицы author_books необходимо исключить CascadeType=REMOVE.

Сделаем это.

Создадим теперь с помощью sql запроса таблицу publisher в которой будут храниться издательства.

Кто знает базы данных должен знать, что связь многие ко многим между двумя таблицами реализуется с помощью промежуточной таблицы, где есть два столбца – id издательства и id книги. Создадим эту таблицу.

Теперь создадим класс созданной только что таблицы publisher. И настроим связь Многие-ко-Многим между этим классом и классом AuthorBooks через промежуточную таблицу.

package HibernateApps; import java.util.ArrayList; import javax.persistence.*; @Entity @Table(name = “publisher”) public class Publisher { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name=”id”) private int id; @Column(name=”name”) private String publisherName; //Теперь используем аннотацию //@ManyToMany (Многие-ко-многим). //многие Publisher ко многим AuthorBooks. //Важно убрать CascadeType.REMOVE чтобы //при удалении из БД какой-то из книги //не удалялись из БД издательства @ManyToMany(cascade = {CascadeType.DETACH, CascadeType.REFRESH, CascadeType.PERSIST, CascadeType.MERGE}) //Теперь настраиваем связи таблицы publisher //с таблицей author_books через промежуточную //таблицу author_books_publisher. @JoinTable( Имя промежуточной таблицы. name = “authours_books_publisher”, //Указываем название атрибута //промежуточной таблицы в котором //хранятся идентификаторы строк //из таблицы publisher. joinColumns=@JoinColumn(name=”publisher_id”), //Указываем название атрибута //промежуточной таблицы в котором //хранятся идентификаторы строк //из таблицы author_books. inverseJoinColumns=@JoinColumn(name=”authorbook_id”)) private List authorbook; public Publisher() { } public Publisher(String publisherName) { this.publisherName = publisherName; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getPublisherName() { return publisherName; } public void setPublisherName( String publisherName) { this.publisherName = publisherName; } public List getAuthorbook() { return authorbook; } public void setAuthorbook( List authorbook) { this.authorbook = authorbook; } //Для связывания объекта книги //с объектом издательства просто //добавляем объект книги в List //объекта издательства. Тогда при //добавлении в БД издательства, через //объект издательства добавляются в БД //и книги находящиеся в List //в этом объекте издательства. public void setOneBook( AuthorBooks authorbook){ if (this.authorbook==null) { this.authorbook = new ArrayList<>(); } this.authorbook.add(authorbook); } @Override public String toString() { return “Publisher [id=” + id + “, publisherName=” + publisherName + “, authorbook=” + authorbook + “]”; } }

Теперь в классе таблицы author_books настроим связь Многие-ко-Многим между этим классом и классом Publisher также через промежуточную таблицу.

Связь настраивается таким же образом как и в классе Publisher, только меняем местами publisher_id и authorbook_id

package HibernateApps; import java.util.ArrayList; import java.util.List; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.ManyToOne; import javax.persistence.Table; @Entity @Table(name = “author_books”) public class AuthorBooks { @Id @GeneratedValue( strategy=GenerationType.IDENTITY ) @Column(name=”id”) private int id; @Column(name=”name”) private String bookName; @ManyToOne(cascade ={CascadeType.DETACH, CascadeType.REFRESH, CascadeType.PERSIST, CascadeType.MERGE}) @JoinColumn(name=”author_id”) private Author author; //Также используем аннотацию //@ManyToMany (Многие-ко-Многим). //Многие AuthorBooks ко многим Publisher. //Важно убрать CascadeType.REMOVE чтобы //при удалении из БД какого-то из издательств //не удалялись из БД книги напечатанные им. @ManyToMany(cascade ={CascadeType.DETACH, CascadeType.REFRESH, CascadeType.PERSIST, CascadeType.MERGE}) @JoinTable(name=”authorbooks_publisher”, //Связь с таблицей publisher //через промежуточную таблицу //в этом классе настраиваем также //как и в классе Publisher только //как можно увидеть ниже //в joinColumns теперь authorbook_id, //а в inverseJoinColumns //теперь publisher_id. joinColumns= @JoinColumn(name=”authorbook_id”), inverseJoinColumns= @JoinColumn(name=”publisher_id”)) private List publisher; public AuthorBooks () { } public AuthorBooks(String bookName) { this.bookName = bookName; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getBookName() { return bookName; } public void setBookName(String bookName) { this.bookName = bookName; } public Author getAuthor() { return author; } public void setAuthor(Author author) { this.author = author; } @Override public String toString() { return “Book [id=” + id + “, bookName=” + bookName + “]”; } }

Пример программы со связью Многие-ко-Многим:

package HibernateApps; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class HibernateApp { public static void main(String[] args) { //Добавим Publisher в sessionfactory SessionFactory sessionFactory = new Configuration() .configure(“hibernate.cfg.xml”) .addAnnotatedClass(Author.class) .addAnnotatedClass(AuthorInfo.class) .addAnnotatedClass(AuthorBooks.class) .addAnnotatedClass(Publisher.class) .buildSessionFactory(); Session session = sessionFactory.getCurrentSession(); try { session.beginTransaction(); //создаем издательства Publisher publisher = new Publisher(“Yakaboo”); Publisher publisher1 = new Publisher(“Vivat”); Publisher publisher2 = new Publisher(“IPIO”); //извлем три книги из БД AuthorBooks authorbook = session.get(AuthorBooks.class,1); AuthorBooks authorbook1 = session.get(AuthorBooks.class,2); AuthorBooks authorbook2 = session.get(AuthorBooks.class,3); //Связываем первое издательство //с первой и третьей книгой. publisher.setOneBook(authorbook); publisher.setOneBook(authorbook2); //Связываем второе издательство //с первой, второй и третьей книгой. publisher1.setOneBook(authorbook); publisher1.setOneBook(authorbook1); publisher1.setOneBook(authorbook2); //Связываем третье издательство //со второй и третьей книгой. publisher2.setOneBook(authorbook1); publisher2.setOneBook(authorbook2); //сохраняем издательства в базу session.save(publisher); session.save(publisher1); session.save(publisher2); session.getTransaction().commit(); } catch (Exception e) { session.getTransaction().rollback(); e.printStackTrace(); } finally{ session.close(); } } }

Давайте запустим нашу программу.

Как видим, сначала произошло три select запроса на выборку книг (как мы помним, мы извлекали из БД три книги с помощью get).

Далее произошла вставка (insert) трех издательств в таблицу publisher и потом произошло связывание издательств и книжек посредством вставки идентификаторов в промежуточную таблицу.

Как видим, вставка издательств в таблицу publisher произошла успешно. Можно убедиться, что в промежуточной таблице книги и издательства связаны в соответствии с тем как мы их связывали в программе

Сборщик проектов Maven

Узнайте, как Maven упрощает управление зависимостями и сборку Java-проектов. Освойте pom.xml, локальный репозиторий и структуру проектов.

Time to read: 17

Создание Maven веб-проекта в Eclipse IDE

Пошаговая инструкция по созданию Maven веб-проекта в Eclipse. Настройте структуру, зависимости и archetype для быстрого старта разработки.

Time to read: 16

Настройка файла pom.xml в Maven

Полное руководство по настройке pom.xml в Maven: добавление зависимостей, управление плагинами и конфигурация сборки Java-проектов.

Time to read: 20