Создание CRUD-приложения с Hibernate и Spring
Last updated: 11 мая 2025 г.В этом уроке создадим простое CRUD
приложение с использованием hibernate.
CRUD это аббревиатура:
- C (Create) – Добавить новые данные в БД.
- R (Read) – Прочитать данные из БД.
- U (Update) – Обновить данные в БД.
- D (Delete) – удалить данные из БД.
Наше приложение будет реализовывать все эти четыре операции.
Эти операции будут производиться с таблицей. Пускай это будет таблица "Актеры"
с аттрибутами "Имя актера"
и "Самый известный фильм"
.
Приложение будет выглядеть примерно так:

Как видим, здесь есть ссылка add actor, которая ведет на другую страницу на которой есть форма для добавления нового актера в таблицу с актерами. Это Create операция.
Рядом с каждым актером есть ссылка update, которая ведет на другую страницу на которой есть форма для обновления данных актера рядом с которым была нажата эта ссылка. Это, очевидно, Update операция.
Также рядом с каждым актером есть ссылка для удаления конкретного актера. Это, очевидно, Delete операция.
Read же операция, это само присутствие на странице списка актеров. То есть, чтобы отобразить на странице список актеров, нужно их сначала выбрать из БД, то есть совершить Read операцию.
Давайте для начала создадим таблицу actor
, в которой будут храниться актеры. И сразу туда добавим пару актеров.

Создадим Мавен приложение с такой структурой и файлами:

В папке entity
хранятся классы связанные с таблицами в БД с помощью hibernate. В данном случае будет всего один класс actor
, который будет связан с таблицей с актерами.
В папке controller
есть класс контроллер, который будет принимать запросы, перенаправлять на страницы и совершать CRUD операции через DAO объект, который находиться в папке dao.
Dao
объект нужен для взаимодействия с БД. О нем подробнее далее.
Также можно увидеть три страницы jsp. ListOfActors
отображает всех актеров из таблицы с актерами (это та страница, которую можно увидеть на картинке выше), страница ActorJSPNewActorForm
на которой можно добавить нового актера в БД и страница ActorJSPUpdateForm
на которой можно обновить актера в БД.
Теперь давайте добавим необходимые зависимости в pom файл, чтобы приложение работало.
1<?xml version="1.0" encoding="UTF-8"?>
2<project xmlns="http://maven.apache.org/POM/4.0.0"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
5 http://maven.apache.org/xsd/maven-4.0.0.xsd">
6 <modelVersion>4.0.0</modelVersion>
7 <groupId>com.MavenWebApps</groupId>
8 <artifactId>hibernateCRUDapp</artifactId>
9 <packaging>jar</packaging>
10 <version>0.0.1-SNAPSHOT</version>
11 <name>hibernateCRUDapp Maven Webapp</name>
12 <url>http://maven.apache.org</url>
13
14 <dependencies>
15 <!--
16 Подключим в проект три необходимые
17 спринг библиотеки. Одна для поддержки MVC,
18 другая для поддержки транзакций,
19 третья для поддержки orm в нашем приложении
20 -->
21 <dependency>
22 <groupId>org.springframework</groupId>
23 <artifactId>spring-webmvc</artifactId>
24 <version>5.3.0</version>
25 </dependency>
26
27 <dependency>
28 <groupId>org.springframework</groupId>
29 <artifactId>spring-tx</artifactId>
30 <version>5.3.0</version>
31 </dependency>
32
33 <dependency>
34 <groupId>org.springframework</groupId>
35 <artifactId>spring-orm</artifactId>
36 <version>5.3.0</version>
37 </dependency>
38
39 <!-- Подключаем hibernate -->
40 <dependency>
41 <groupId>org.hibernate</groupId>
42 <artifactId>hibernate-core</artifactId>
43 <version>5.3.26.Final</version>
44 </dependency>
45
46 <!-- Подключаем mysql -->
47 <dependency>
48 <groupId>mysql</groupId>
49 <artifactId>
50 mysql-connector-java
51 </artifactId>
52 <version>8.0.32</version>
53 </dependency>
54
55 <!-- Подключаем c3p0.
56 Дальше пригодится, увидите. -->
57 <dependency>
58 <groupId>com.mchange</groupId>
59 <artifactId>c3p0</artifactId>
60 <version>0.9.5.5</version>
61 </dependency>
62
63 <!-- Подключаем Сервлеты, jsp и jstl -->
64 <dependency>
65 <groupId>javax.servlet</groupId>
66 <artifactId>
67 javax.servlet-api
68 </artifactId>
69 <version>3.1.0</version>
70 </dependency>
71
72 <dependency>
73 <groupId>javax.servlet</groupId>
74 <artifactId>jstl</artifactId>
75 <version>1.2</version>
76 </dependency>
77
78 <dependency>
79 <groupId>junit</groupId>
80 <artifactId>junit</artifactId>
81 <version>3.8.1</version>
82 <scope>test</scope>
83 </dependency>
84 </dependencies>
85
86 <build>
87 <plugins>
88 <plugin>
89 <groupId>
90 org.apache.maven.plugins
91 </groupId>
92 <artifactId>maven-war-plugin</artifactId>
93 <version>3.4.0</version>
94 <configuration>
95 <failOnMissingWebXml>
96 false
97 </failOnMissingWebXml>
98 </configuration>
99 </plugin>
100 </plugins>
101 </build>
102</project>
Как мы помним, в обычном hibernate приложении подключение к базе настраивается в файле hibernate.cfg.xml.
В MVC же приложении подключение настраивается в applicationContext.xml.
Здесь же настраивается и бин SessionFactory
, то есть создавать объект SessionFactory
java кодом, как в обычном hibernate приложении не придется, создавать новые объекты сессий можно будет через заранее сконфигурированный в applicationContext бин.
1<?xml version="1.0" encoding="UTF-8"?>
2<beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xmlns:context="http://www.springframework.org/schema/context"
5 xmlns:tx="http://www.springframework.org/schema/tx"
6 xmlns:mvc="http://www.springframework.org/schema/mvc"
7 xsi:schemaLocation="
8 http://www.springframework.org/schema/beans
9 http://www.springframework.org/schema/beans/spring-beans.xsd
10 http://www.springframework.org/schema/context
11 http://www.springframework.org/schema/context/spring-context.xsd
12 http://www.springframework.org/schema/mvc
13 http://www.springframework.org/schema/mvc/spring-mvc.xsd
14 http://www.springframework.org/schema/tx
15 http://www.springframework.org/schema/tx/spring-tx.xsd">
16
17 <!-- Как и раньше указываем путь где будет производиться
18 поиск классов со спринг аннотациями для создания
19 на основе них бинов. -->
20 <context:component-scan
21 base-package="com/MavenWebAps/hibernateCRUDap"/>
22 <mvc:annotation-driven/>
23
24 <!--Как и раньше конфигурируем путь к вьюхам как и раньше.-->
25 <bean
26 class="org.springframework.web.servlet
27 .view.InternalResourceViewResolver">
28 <property name="prefix" value="/WEB-INF/jsp/"/>
29 <property name="suffix" value=".jsp"/>
30 </bean>
31
32 <!-- В бине класса ComboPooledDataSource указываем
33 данные подключения к базе и ее настройки.
34 То есть пароль, имя базы и т.д. как обычно. -->
35 <bean id="myDataSource" class="com.mchange.v2.
36 c3p0.ComboPooledDataSource" destroy-method="close">
37 <property name="driverClass"
38 value="com.mysql.jdbc.Driver" />
39 <property name="jdbcUrl"
40 value="jdbc:mysql://localhost/storage" />
41 <property name="user" value="root" />
42 <property name="password" value="07031998mike" />
43 <!-- these are connection pool properties for C3P0 -->
44 <property name="minPoolSize" value="5" />
45 <property name="maxPoolSize" value="20" />
46 <property name="maxIdleTime" value="30000" />
47 </bean>
48 <!--
49 Верхний бин внедряется в бин фабрики сессий.
50 В обычном hibernate приложении как мы помним конфигурация
51 фабрики сессий происходила так: SessionFactory sessionFactory
52 = new Configuration().configure("hibernate.cfg.xml").
53 Здесь же бин myDataSource ВМЕСТО файла hibernate.cfg.xml,
54 бин sessionFactory ВМЕСТО объекта SessionFactory.
55 Бину sessionFactory передается конфигурация
56 в бине myDataSource.
57 -->
58 <bean id="sessionFactory" class="org.springframework.orm.
59 hibernate5.LocalSessionFactoryBean">
60 <property name="dataSource" ref="myDataSource" />
61 <!--
62 Также фабрике сессий как мы помним передавались
63 классы таблиц. Здесь же передаем бин фабрики
64 путь к классам таблиц. Они будут храниться в папке entity
65 -->
66 <property name="packagesToScan"
67 value="com/MavenWebAps/hibernateCRUDap/entity" />
68 <property name="hibernateProperties">
69 <props>
70 <prop key="hibernate.dialect">
71 org.hibernate.dialect.MySQLDialect
72 </prop>
73 <prop key="hibernate.show_sql">true</prop>
74 </props>
75 </property>
76 </bean>
77
78 <bean id="myTransactionManager"
79 class="org.springframework.orm.hibernate5
80 .HibernateTransactionManager">
81 <!-- Внедряем нашу фабрику в бин для обработки хибернейт
82 транзакций аннотацией @Transactional.
83 Оней подробней дальше -->
84 <property name="sessionFactory" ref="sessionFactory"/>
85 </bean>
86
87 <!-- здесь включаем поддержку @Transactional
88 передавая бин выше. -->
89 <tx:annotation-driven
90 transaction-manager="myTransactionManager"/>
91</beans>
Создадим класс ранее созданной таблицы actor. Здесь ничего нового.
1package com.MavenWebAps.hibernateCRUDap.entity;
2
3import javax.persistence.Column;
4import javax.persistence.Entity;
5import javax.persistence.Table;
6import javax.persistence.GeneratedValue;
7import javax.persistence.GenerationType;
8import javax.persistence.Id;
9
10@Entity
11@Table(name = "actor")
12public class Actor {
13
14 @Id
15 @GeneratedValue(strategy = GenerationType.IDENTITY)
16 @Column(name = "id")
17 private int id;
18
19 @Column(name = "name")
20 private String actorName;
21
22 @Column(name = "most_famous_film")
23 private String film;
24
25 public Actor() {
26 }
27
28 public Actor(String actorName, String film) {
29 this.actorName = actorName;
30 this.film = film;
31 }
32
33 public int getId() {
34 return id;
35 }
36
37 public void setId(int id) {
38 this.id = id;
39 }
40
41 public String getActorName() {
42 return actorName;
43 }
44
45 public void setActorName(String actorName) {
46 this.actorName = actorName;
47 }
48
49 public String getFilm() {
50 return film;
51 }
52
53 public void setFilm(String film) {
54 this.film = film;
55 }
56
57 @Override
58 public String toString() {
59 return "Actor [id=" + id +
60 ", actorName=" + actorName +
61 ", film=" + film + "]";
62 }
63}
Давайте для начала создадим интерфейс на основе которого будем создавать DAO класс.
1package com.MavenWebAps.hibernateCRUDap.dao;
2
3import java.util.List;
4
5public interface ActorDAO {
6 public Actor getActor(int actorId);
7 public void setActor(Actor actor);
8 public List<Actor> getListOfActors();
9 public void deleteActor(int actorid);
10}
Через DAO бин, который будет внедряться в контроллер, будут производиться CRUD операции с БД.
В DAO классе ниже можно увидеть методы с помощью которых происходит непосредственное взаимодействие с БД с помощью hiberante.
Также важно отметить, что DAO бин, это особенный бин, класс которого помечается аннотацией @Repository
.
1package com.MavenWebAps.hibernateCRUD.dao;
2
3import java.util.List;
4
5//Также как и @Controller аннотация @Repository
6//наследуется от @Component, потому спринг
7//анализирует этот класс как особый бин.
8//Этой аннотацией помечется DAO объект.
9//Спринг распознает объект помеченный этой аннотацией
10//как дао объект и благодаря этому
11//в нем можно использовать @Transactional.
12@Repository
13//Помните паттерн ДАО. Где все низкоуровневое
14//взаимодействие с ресурсом (в нашем случае с БД)
15//скрывалось в дополнительном классе. В Spring MVC он
16//используется для сокрытия низкоуровневого
17//взаимодействия с базой с помощью hibernate.
18//В этом классе мы создаем методы для взаимодействия
19//с базой. В конторллере же мы используем эти методы,
20//то есть никакого hibernate кода в контроллере нет
21//и не должно быть.
22public class ActorDAOImpl implements ActorDAO {
23
24 @Autowired
25 //Внедряем sessionFactory (такой же id имеет бин фабрики
26 //сессий который мы конфигурировали в applicationContext).
27 private SessionFactory sessionFactory;
28
29 //READ
30 //Ниже метод для выборки актера из базы по id.
31 //Все что выполняется в методе помеченном @Transactional
32 //выполняется в отдельной транзакции. То есть это просто
33 //некоторое упрощение чтобы нам не приходилось писать
34 //session.beginTransaction(); и
35 //session.getTransaction().commit();.
36 @Transactional
37 public Actor getActor(int actorId) {
38 Session session = sessionFactory.getCurrentSession();
39 return session.get(Actor.class, actorId);
40 }
41
42 //CREATE, UPDATE
43 //метод для вставки актера в базу ли обновления
44 //актера в базе.
45 @Transactional
46 public void setActor(Actor actor) {
47 Session session = sessionFactory.getCurrentSession();
48 //Есть довольно удобный метод saveOrUpdate, который
49 //будет смотреть на id присланного объекта actor.
50 //Если актер с таким id уже есть в таблице с актерами
51 //то этот метод обновляет строку таблицы с таким id,
52 //а если такого нет то добавляет присланный объект
53 //в таблицу.
54 session.saveOrUpdate(actor);
55 }
56
57 //Тоже READ только всех актеров,
58 //а не одного как метод getActor.
59 @Transactional
60 public List<Actor> getListOfActors() {
61 Session session = sessionFactory.getCurrentSession();
62 return session.createQuery("from Actor",
63 Actor.class).getResultList();
64 }
65
66 //DELETE
67 //метод для удаления актера из базы по id
68 @Transactional
69 public void deleteActor(int actorid) {
70 Session session = sessionFactory.getCurrentSession();
71 session.createQuery(
72 "delete from Actor where id=:actorid")
73 .setParameter("actorid", actorid).executeUpdate();
74 }
75}
Теперь создадим контроллер, который будет перенаправлять на страницы и совершать CRUD операции через DAO бин, который внедряется в контроллер.
1package com.MavenWebApps.hibernateCRUD.controller;
2
3import org.springframework.beans.factory.annotation.Autowired;
4import org.springframework.stereotype.Controller;
5import org.springframework.ui.Model;
6import org.springframework.web.bind.annotation.ModelAttribute;
7import org.springframework.web.bind.annotation.RequestMapping;
8import org.springframework.web.bind.annotation.RequestParam;
9
10import com.MavenWebApps.hibernateCRUD.dao.ActorDAO;
11import com.MavenWebApps.hibernateCRUD.entity.Actor;
12
13import java.util.List;
14
15@Controller
16@RequestMapping("/actor")
17public class CRUDController {
18
19 //Внедряем созданный DAO объект (бин) чтобы
20 //через него взаимодействовать с базой.
21 @Autowired
22 private ActorDAO actorDao;
23
24 //READ
25 //Как можно увидеть этот обработчик выбирает
26 //из БД всех актеров через DAO объект
27 //и перенаправляет их в аттрибуте
28 //listofactors на страницу ListOfActors.jsp
29 //где все актеры из аттрибута будут отображены.
30 @RequestMapping("/getListofActors")
31 public String getListofActors(Model model) {
32 model.addAttribute("listofactors",
33 actorDao.getListofActors());
34 return "ListofActorsJSP";
35 }
36
37
38 //Этот обработчик перенаправляет на страницу
39 //ActorJSPUpdateForm.jsp на которой можно
40 //совершить UPDATE актера. Как видим в обработчик
41 //передаеться id актера, по этому id выбираеться
42 //из БД актер и помещаеться в аттрибут someactor
43 //и данные этого актера из этого аттрибута будут
44 //отображаться на странице ActorJSPUpdateForm.jsp.
45 //Это просто нужно чтобы при обновлении данных
46 //актера мы видели на странице и предидущие
47 //данные обновляемого актера.
48 @RequestMapping("/showFormForUpdating")
49 public String showFormForUpdating(
50 @RequestParam("actorId") int actorId,
51 Model model) {
52 model.addAttribute("someactor",
53 actorDao.getActor(actorId));
54 return "ActorJSPUpdateForm";
55 }
56
57
58 //Этот обработчик перенаправляет на страницу
59 //ActorJSPNewActorForm.jsp на которой можно
60 //совершить CREATE актера. То есть создать
61 //нового актера и поместить в таблицу с актерами.
62 //Как видим здесь создаеться новый обьект актера
63 //и помещаеться в аттребут someactor, который
64 //будет доступен на странице
65 //ActorJSPNewActorForm.jsp. Там этот обьект будет
66 //заполняться через форму и добавляться в БД.
67 @RequestMapping("/showFormForSetting")
68 public String setActor(Model model) {
69 model.addAttribute("someactor",
70 new Actor());
71 return "ActorJSPNewActorForm";
72 }
73
74
75 //CREATE, UPDATE
76 //Этот обработчик просто добавляет актера
77 //в таблицу или обновляет актера в таблице
78 //с актерами и перенаправляет обратно
79 //на страницу со списком актеров через
80 //обработчик getListofActors.
81 @RequestMapping("/setActor")
82 public String setActor(@ModelAttribute("someactor") Actor actor, Model model){
83 actorDao.setActor(actor);
84 //ВАЖНЫЙ момент чтобы перейти в какой-то
85 //обработчик контроллера, а не на какую-то
86 //страницу пишем redirect:…
87 return "redirect:/actor/getListofActors";
88 }
89
90 //DELETE
91 //Этот обработчик удаляет актера из таблицы
92 //с актерами и перенаправляет обратно
93 //на страницу со списком актеров через
94 //обработчик getListofActors.
95 @RequestMapping("/deleteActor")
96 public String deleteActor(
97 @RequestParam("actorId") int actorid,
98 Model model) {
99 actorDao.deleteActor(actorid);
100 return "redirect:/actor/getListofActors";
101 }
102}
Создадим главную страницу на которой будут отображаться все актеры из таблицы actor, и даются ссылки для create, updete, delete актеров.
1<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
2<%@ page isELIgnored="false" %>
3<html>
4<!--
5На эту страницу происходит переход при
6переходе в обработчик getListOfActors.
7-->
8<head>
9 <title>CRUD JSP</title>
10</head>
11<body>
12<!-- На этой странице выводятся все актеры из таблицы actor,
13и даются ссылки для create, update, delete актеров. -->
14<table>
15 <!-- Для вывода каждой строки таблицы actor
16 можем пользоваться forEach. Строки таблицы actor
17 хранятся в атрибуте listofactors. Они сохраняются
18 туда при переходе в обработчик getListOfActors,
19 который также переводит нас на эту страницу. -->
20 <c:forEach var="singleActor" items="${listofactors}">
21 <!--
22 Если хотим поместить параметр в какую-то ссылку
23 можно использовать <c url>. То есть в результате выполнения
24 тега <c url> ниже в updateLink будет храниться такая ссылка:
25 showFormForUpdating?actorId={id текущей строки таблицы actor}.
26 При переходе по этой ссылке будет вызываться обработчик
27 showFormForUpdating, в который будет передаваться id актера.
28 -->
29 <c:url var="updateLink" value="showFormForUpdating">
30 <c:param name="actorId" value="${singleActor.id}" />
31 </c:url>
32 <!-- Здесь подобным образом формируется ссылка для удаления -->
33 <c:url var="deleteLink" value="deleteActor">
34 <c:param name="actorId" value="${singleActor.id}" />
35 </c:url>
36 <tr>
37 <!-- Выводим на страницу данные текущего
38 в цикле forEach актера. -->
39 <td>${singleActor.actorName}</td>
40 <td>${singleActor.film}</td>
41 <td><a href="${updateLink}">update</a> / </td>
42 <td><a href="${deleteLink}">delete</a></td>
43 </tr>
44 </c:forEach>
45 <tr>
46 <!-- Эта ссылка переводит в обработчик showFormForSetting,
47 который переводит на страницу с формой, через которую можно
48 добавить нового актера в таблицу. -->
49 <td><a href="showFormForSetting">add actor</a></td>
50 </tr>
51</table>
52</body>
53</html>
Теперь создадим страницу с формой для добавления нового актера в таблицу актеров.
1<%@ taglib prefix="form"
2 uri="http://www.springframework.org/tags/form"%>
3<%@ page isELIgnored="false"%>
4<html>
5<!--
6 По нажатию на ссылку add actor
7 на странице ListOfActors происходит переход
8 на эту страницу.
9-->
10<head>
11 <title>Create JSP</title>
12</head>
13<body>
14<!-- Здесь форма для добавления.
15Как видим эта форма привязывается к пустому объекту
16актера, который был сюда прислан в аттрибуте someactor
17обработчиком showFormForSetting.
18Этот пустой объект заполняется через форму ниже
19и отсылается в обработчик setActor, который добавляет
20этот заполненный объект в БД через DAO бин. -->
21<form:form action="setActor" modelAttribute="someactor">
22 Name: <form:input path="actorName"/> <br/>
23 Most famous film: <form:input path="film"/> <br/>
24 <input type="submit" value="submit"/> <br/>
25</form:form>
26</body>
27</html>
Теперь создадим страницу с формой для обновления данных существующего актера.
1<%@ taglib prefix="form"
2 uri="http://www.springframework.org/tags/form"%>
3<%@ page isELIgnored="false"%>
4<html>
5<!--
6 По нажатию на ссылку update на странице ListOfActorsJSP
7 происходит переход на эту страницу.
8 При этом на эту страницу передается актер
9 напротив которого была нажата ссылка update.
10 Он находится в аттрибуте someactor.
11-->
12<head>
13 <title>Update JSP</title>
14</head>
15<body>
16
17<!-- В двух строках ниже просто отобразим
18старую информацию актера в someactor
19чтобы пользователю было ее видно -->
20Old Info: Old name: ${someactor.actorName},
21Old film: ${someactor.film}
22<!-- Через эту форму обновляем актера
23в аттрибуте someactor. И обновленный актер
24опять таки будет отослан в обработчик setActor,
25который через Dao бин обновляет актера в БД. -->
26<form:form action="setActor" modelAttribute="someactor">
27 New Info: <br/>
28 <!--Помним из прошлых уроков что при загрузке формы
29 на странице сразу вызывается геттер переменной
30 указанной в path. В path указывается переменная
31 объекта, который находится в переданном в форму
32 аттрибуте (someactor). Если в форме не будет
33 вызван path какой-то переменной переданного
34 объекта в аттрибуте то очевидно геттер для нее
35 не вызовится и в результирующем объекте в аттрибуте,
36 который будет отправлен формой эта переменная будет
37 пуста поскольку для нее не был вызван геттер
38 и в нее ничего не записалось. Поэтому если нам
39 нужно сохранить какие-то переменные переданной
40 на страницу старой версии объекта актера
41 в обновленном формой объекте актера, который
42 будет отправляться формой (в нашем случае нам
43 необходимо сохранить id), можно просто вызывать path
44 с помощью тега hidden. Этот тег больше ничего
45 не делает кроме вызова path.
46 То есть строка ниже нужна просто для вызова геттера
47 переменной id в объекте в аттрибуте.
48 -->
49 <form:hidden path="id"/>
50 Name: <form:input path="actorName"/> <br/>
51 Most famous film: <form:input path="film"/> <br/>
52 <input type="submit" value="submit"/> <br/>
53</form:form>
54</body>
55</html>
Давайте же перейдем на главную страницу со списком актеров. Как мы помним, на эту страницу можно перейти через обработчик getListOfActors
. Сделаем это:

Как видим, обработчик getListOfActors
успешно выбрал актеров из БД и они успешно вывелись на странице.
Давайте теперь добавим актера в БД. Для этого нажмем на add actor. В результате этого произойдет переход в обработчик showFormForSetting
, который создает новый объект актера, который будет заполняться формой на странице на которую переводит этот обработчик. Ниже эта страница. Заполним форму новым актером и нажмем submit.

По нажатию на submit происходит вызов обработчика setActor
, который добавляет актера в БД и перенаправляет в обработчик getListOfActors
, который перенаправляет обратно на главную страницу со всеми актерами.

Как видим, новый актер успешно был добавлен в БД и отображен на странице.
Теперь давайте нажмем на Update рядом с актером Johnny Depp, чтобы можно было обновить данные этого актера. По нажатию происходит вызов обработчика showFormForUpdating
, который перенаправляет на страницу для обновления данных актера. Как можно увидеть, этот обработчик успешно выбрал из БД текущие данные актера Johnny Depp, которые впоследствии были отображены на странице.

Объект актера Johnny Depp извлеченный обработчиком был связан с формой для обновления данных актера. Давайте изменим этой формой название фильма и нажмем submit.

По нажатию на submit происходит вызов обработчика setActor
, который обновляет данные актера в БД и перенаправляет в обработчик getListOfActors
, который перенаправляет обратно на главную страницу со всеми актерами.

Как видим, данные актера Johnny Depp, а именно название фильма, успешно обновились на странице, а значит и в БД.
Давайте теперь удалим из БД последний фильм, для этого просто нажмем Delete напротив актера Jeffrey Dean Morgan.

Как видим, актер успешно удалился на странице, а значит и в БД.
Дополнительные материалы
Документация Spring по транзакциям
Тестирование Hibernate-приложений
Безопасность CRUD-приложений
Следующие уроки
Hibernate CRUD приложение с сервисным уровнем
23
мин.
Что такое REST API?
21
мин.
Первое Spring REST API-приложение
22
мин.