Настройка связи Один-ко-Многим в Hibernate

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

Создадим еще одну таблицу "Книги авторов", которая будет связана с таблицей author. В одной таблице хранятся авторы, а в другой их книги.

У каждого автора много книг, но у каждой книги только один автор. То есть связь – один автор ко многим книгам.

При удалении автора должны удаляться и его книги из другой таблицы. При удалении книги его автор не должен удаляться. Сделаем это.

Создадим теперь с помощью sql запроса таблицу author_books, в которой будут храниться книги авторов и которая будет связана с таблицей author с помощью внешнего ключа author_id.

Теперь создадим класс созданной только что таблицы author_books. И настроим теперь связь между этим классом и классом Author

Теперь в классе таблицы author настраиваем обратную связь с новым классом.

package HibernateApps; import java.util.List; @Entity //это класс с таблицы author @Table (name = “author”) public class Author { @Id @GeneratedValue( strategy=GenerationType.IDENTITY ) @Column(name=”id”) private int id; @Column(name=”name”) private String authorName; @OneToOne(cascade={CascadeType.ALL}) @JoinColumn(name=”author_info_id”) private AuthorInfo authorInfo; @OneToMany(fetch=FetchType.EAGER, //О том что такое EAGER //в следующем уроке. mappedBy=”author”, //Пускай будут включены //все типы каскадных //операций – CascadeType.ALL. //При удалении //автора пусть удаляются //из БД и все его книги. cascade = CascadeType.ALL) //как видим многие книжки автора //будут записываться в список. private List authorbooks; public Author() { } public Author(String authorName) { this.authorName = authorName; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getAuthorName() { return authorName; } public void setAuthorName( String authorName) { this.authorName = authorName; } public AuthorInfo getAuthorInfo() { return authorInfo; } public void setAuthorInfo( AuthorInfo authorInfo) { this.authorInfo = authorInfo; } //добавляем геттер сеттер для списка public List getAuthorBooks(){ return authorbooks; } public void setAuthorBooks( List authorbooks){ this.authorbooks = authorbooks; } @Override public String toString() { return “Author [id=” + id + “, authorName=” + authorName + “, authorInfo=” + authorInfo + “, authorbooks=” + authorbooks + “]”; } }

В программе же создадим объект автора и три объекта книг, свяжем эти книги с объектом автора, и добавим эти все объекты в БД.

Потом извлечем из БД автора в объект автора. Вместе с автором также должны извлечься и связанные с ним книги, которые сохраняться в объекте автора.

Далее удалим одну книгу из БД через объект книги, который храниться в объекте автора. При этом связанный с этой книгой автор не должен удалиться из БД.

package HibernateApps; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class HibernateApp { public static void main(String[] args) { //Добавим AuthorBooks в sessionFactory. SessionFactory sessionFactory = new Configuration() .configure(“hibernate.cfg.xml”) .addAnnotatedClass(Author.class) .addAnnotatedClass(AuthorInfo.class) .addAnnotatedClass(AuthorBooks.class) .buildSessionFactory(); Session session = sessionFactory.getCurrentSession(); try { session.beginTransaction(); //создадим объект Author Author author = new Author(“JJ Rouling”); //и добавим его в таблицу author session.save(author); //Теперь создадим три объекта книги. //Это книги автора, которого мы только //что добавили в БД. AuthorBooks authorbook = new AuthorBooks(“Harry Potter 1”);; AuthorBooks authorbook1 = new AuthorBooks(“Harry Potter 2”); AuthorBooks authorbook2 = new AuthorBooks(“Harry Potter 3”); //поэтому связываем автора с книгами authorbook.setAuthor(author); authorbook1.setAuthor(author); authorbook2.setAuthor(author); //сохраняем книги в базу session.save(authorbook); session.save(authorbook1); session.save(authorbook2); //Закоммитим и начнем //новую сессию и транзакцию. session.getTransaction().commit(); session=sessionFactory.getCurrentSession(); session.beginTransaction(); //Извлечем только что добавленного в БД //автора из БД. Вместе с ним извлекуться //связанные с ним книги и будут храниться //в объекте автора author1. Author author1 = session.get(Author.class, 1); //Можем их увидеть в консоли. System.out.println(author1); //Удалим первую книгу автора из БД. //При удалении книги из БД автор //этой книги из БД не удаляется //как и было задумано. session.delete( author1.getAuthorBooks().get(0)); //Также удалить нужно первую книгу //и из списка книг в объекте author1. author1.getAuthorBooks().remove(0); //Извлечем автора из БД уже с двумя //книгами. Author author2 = session.get(Author.class, 1); //Удалим теперь автора из БД. //При удалении автора из БД //удаляються и его книги из БД //как и было задумано. session.delete(author2); //Извлечем автора из БД еще раз //Не должно получиться так как мы //его только что удалили из БД. Author author3 = session.get(Author.class, 1); session.getTransaction().commit(); //Объект author2 должен содержать //две книги после удаления одной из БД. //Проверим это. System.out.println(author2); //Объект author3 должен быть пуст //после удаления его из БД. //Проверим это. System.out.println(author3); } catch (Exception e) { session.getTransaction().rollback(); e.printStackTrace(); } finally { session.close(); } } }

И потом удалим автора из БД через объект автора. При этом связанные с этим автором книги тоже должны удалиться из БД.

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

Как видим, произошла вставка в БД четырех объектов, то есть автора и его книг.

После извлечения автора из БД можно увидеть в консоли, что он содержит в себе все книги, которые связаны с ним в БД.

После этого происходит запрос на удаление одной книги из БД через объект книги, который хранился в author1.

Далее можно увидеть, что происходят запросы на удаление из БД остальных книг вместе с автором через объект author2.

После этого можно увидеть содержимое объекта author2. Можно увидеть, что в нем нет одной книги, она была удалена из БД. То есть удаление одной книги автора из БД через объект author1 прошло успешно.

После этого можно увидеть содержимое объекта author3. В нем null поскольку все книги вместе с автором уже были удалены из БД через объект author2.

Типы извлечения данных в Hibernate (fetch types)

Изучите разницу между LAZY и EAGER загрузкой в Hibernate. Узнайте, когда связанные сущности загружаются из БД и как это влияет на производительность приложений.
Time to read: 19

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

Разберитесь с аннотациями @ManyToMany и @JoinTable в Hibernate. Настройте связь между сущностями через промежуточную таблицу.
Time to read: 20

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

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