Форум программистов, компьютерный форум, киберфорум
Наши страницы
Java: Базы данных
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
SoulDrake
0 / 0 / 0
Регистрация: 06.07.2018
Сообщений: 17
1

Операция редактирования в CRUD

29.11.2018, 16:32. Просмотров 1061. Ответов 5

Здравствуйте

Не так давно начал знакомиться с Maven, Spring, Hibernate и т.д. Ну и в качестве небольшой практики решил попробовать сделать CRUD приложение с использованием Spring MVC, MySQL, Hibernate.

У меня получается сделать вывод таблички на странице, добавлять записи, удалять, с этим все хорошо. Но у меня все никак не получается сделать редактирование записи.

Суть такая, есть таблица в базе данных с записями, я пытаюсь по id записи получать ее страницу редактирования, передать туда конкретную запись, соответствующую этому id и изменить ее значения. Но оно почему-то пытается изменять запись с id = 0 (которой естественно нет) и вылетает исключение. И я никак не могу понять, в чем я туплю и как это исправить.

Помогите пожалуйста.

Вот код (это укороченный тестовый вариант приложения, тут только вывод списка и редактирование):

Класс-сущность:
Java
1
2
3
4
5
6
7
8
9
10
@Entity
@Table(name = "test")
public class TestEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    private String name;
 
    // getters and setters
}
Репозиторий:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Repository
public class TestRepositoryIm implements TestRepository {
    @Autowired
    private SessionFactory sessionFactory;
 
    @Override
    public List<TestEntity> list() {
        return sessionFactory.getCurrentSession().createQuery("from TestEntity").list();
    }
 
    @Override
    public void edit(TestEntity testEntity) {
        sessionFactory.getCurrentSession().update(testEntity);
    }
 
    @Override
    public TestEntity get(int id) {
        return sessionFactory.getCurrentSession().get(TestEntity.class, id);
    }
}
Сервис:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Service
public class TestServiceIm implements TestService{
    @Autowired
    private TestRepository testRepository;
    @Override
    @Transactional
    public List<TestEntity> list() {
        return testRepository.list();
    }
 
    @Override
    @Transactional
    public void edit(TestEntity testEntity) {
        testRepository.edit(testEntity);
    }
 
    @Override
    @Transactional
    public TestEntity get(int id) {
        return testRepository.get(id);
    }
}
Контроллер:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Controller
public class TestController {
    @Autowired
    private TestService service;
 
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String list(ModelMap modelMap) {
        List<TestEntity> entities = service.list();
        modelMap.addAttribute("entities", entities);
        return "entities";
    }
 
    @RequestMapping(value = "/edit/{id}", method = RequestMethod.GET)
    public String edition(@PathVariable("id") int id, ModelMap model){
        model.addAttribute("entity", service.get(id));
        return "edition";
    }
 
    @RequestMapping(value = "/edit", method = RequestMethod.POST)
    public String edit(@ModelAttribute("entity") TestEntity testEntity){
        service.edit(testEntity);
        return "redirect:/";
    }
}
Главная страница (entities.jsp):
HTML5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<table>
    <tr>
        <th>id</th>
        <th>name</th>
    </tr>
    <c:forEach var="entity" items="${entities}">
        <tr>
            <td>${entity.id}</td>
            <td>${entity.name}</td>
            <td><a href="/edit/${entity.id}">edit</a></td>
        </tr>
    </c:forEach>
</table>
</body>
</html>
Страница редактирования (edition.jsp):
HTML5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
 
<html>
<head>
    <title>Edit</title>
</head>
<body>
<c:url value="/edit" var="edit"/>
<form:form action="${edit}" method="POST" modelAttribute="entity">
    <label for="name">NAME</label>
    <input type="text" name="name" id="name">
    <input type="submit" value="Edit">
</form:form>
</body>
</html>
Так они выглядят:
Операция редактирования в CRUD


Ну и при нажатии на кнопку вылетает исключение:
HTML5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
HTTP Status 500 – Internal Server Error
Type Exception Report
 
Message Request processing failed; nested exception is org.springframework.orm.hibernate5.HibernateOptimisticLockingFailureException: Object of class [test1.entity.TestEntity] with identifier [0]: optimistic locking failed; nested exception is org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [test1.entity.TestEntity#0]
 
Description The server encountered an unexpected condition that prevented it from fulfilling the request.
 
Exception
 
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.orm.hibernate5.HibernateOptimisticLockingFailureException: Object of class [test1.entity.TestEntity] with identifier [0]: optimistic locking failed; nested exception is org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [test1.entity.TestEntity#0]
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
    org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:901)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:875)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
Root Cause
 
org.springframework.orm.hibernate5.HibernateOptimisticLockingFailureException: Object of class [test1.entity.TestEntity] with identifier [0]: optimistic locking failed; nested exception is org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [test1.entity.TestEntity#0]
    org.springframework.orm.hibernate5.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:286)
    org.springframework.orm.hibernate5.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:798)
    org.springframework.orm.hibernate5.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:634)
    org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:746)
    org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:714)
    org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:533)
    org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:304)
    org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
    com.sun.proxy.$Proxy39.edit(Unknown Source)
    test1.controller.TestController.edit(TestController.java:36)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.lang.reflect.Method.invoke(Method.java:498)
    org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:207)
    org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
    org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800)
    org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:998)
    org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:901)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:875)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
Root Cause
 
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [test1.entity.TestEntity#0]
    org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:2522)
    org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3355)
    org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:3229)
    org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3630)
    org.hibernate.action.internal.EntityUpdateAction.execute(EntityUpdateAction.java:146)
    org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604)
    org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:478)
    org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:356)
    org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)
    org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1454)
    org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:511)
    org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3283)
    org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2479)
    org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:473)
    org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:178)
    org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$300(JdbcResourceLocalTransactionCoordinatorImpl.java:39)
    org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:271)
    org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:98)
    org.springframework.orm.hibernate5.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:622)
    org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:746)
    org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:714)
    org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:533)
    org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:304)
    org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
    com.sun.proxy.$Proxy39.edit(Unknown Source)
    test1.controller.TestController.edit(TestController.java:36)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.lang.reflect.Method.invoke(Method.java:498)
    org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:207)
    org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
    org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800)
    org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:998)
    org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:901)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:875)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
0
Лучшие ответы (1)
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
29.11.2018, 16:32
Ответы с готовыми решениями:

Ссылки в CRUD-таблице на другие CRUD-таблицы
Здравствуйте! Прошу у вас помощи :help: У меня есть список групп: Так выглядит представление...

Добавить на форме редактирования отдельную кнопку для редактирования должностей
Народ нужна помощь кто может добавить на форме редактирования кнопку редактирования должностей...

CRUD-запросы
Всем привет! Пытаюсь потихоньку начать учить NodeJS (да и в принципе JavaScript), и вот, дошел до...

Авторизация и CRUD
Здравствуйте. Использую такую штуку для заполнения базы данных. Вопрос, можно ли к ней прикрутить...

Аватарка в CRUD
Добрый день. У меня задача реализации аватарки в CRUD. Код контроллера using System; using...

5
SoulDrake
0 / 0 / 0
Регистрация: 06.07.2018
Сообщений: 17
29.11.2018, 17:03  [ТС] 2
И еще есть у меня один небольшой вопросик. Чтоб не создавать новую тему спрошу прямо тут.

В общем я видел очень много разных гайдов, уроков, примеров и там очень часто говорится, что поля в Entity классе должны быть объектными типами (ту т.е. Integer вместо int), причем некоторые даже говорят что это прям обязательно должно быть так. Но я так и не понял, почему. Надеюсь кто-нибудь просвятит.
0
SoulDrake
0 / 0 / 0
Регистрация: 06.07.2018
Сообщений: 17
01.12.2018, 00:21  [ТС] 3
Все, вопрос решен.

На stackoverflow один человек подсказал - проблема в том, что я не передавал в контроллер id, так что сервер не знал какую запись изменять. Для решения добавил на форму невидимое поле с id
HTML5
1
<input type="hidden" name="id" value="${id}">
0
KEKCoGEN
Эксперт Java
2230 / 2077 / 536
Регистрация: 28.12.2010
Сообщений: 8,215
01.12.2018, 01:15 4
Лучший ответ Сообщение было отмечено SoulDrake как решение

Решение

Цитата Сообщение от SoulDrake Посмотреть сообщение
Для решения добавил на форму невидимое поле с id
плохое решение. ID объектов никогда не должно передаваться на клиент и приходить с клиента. Для таких целей есть UUID
0
SoulDrake
0 / 0 / 0
Регистрация: 06.07.2018
Сообщений: 17
01.12.2018, 10:33  [ТС] 5
Цитата Сообщение от KEKCoGEN Посмотреть сообщение
плохое решение. ID объектов никогда не должно передаваться на клиент и приходить с клиента. Для таких целей есть UUID
Ясно, буду знать. Я сейчас бегло просмотрел информацию по этому вопросу и насколько я понимаю это все таки более высокий уровень, а я же пока только-только начал знакомство с этим всем. Так что полагаю решение с передачей id на форму приемлемо для начала, просто чтобы на максимально простых примерах понять базовые принципы работы БД, Hibernate и т.д.

Но, когда следующим шагом буду пробовать сделать что-то посложнее, буду иметь это ввиду. Спасибо.
0
KEKCoGEN
Эксперт Java
2230 / 2077 / 536
Регистрация: 28.12.2010
Сообщений: 8,215
01.12.2018, 11:51 6
Цитата Сообщение от SoulDrake Посмотреть сообщение
я понимаю это все таки более высокий уровень
вместо одной переменной передавать другую это не более высокий уровень.
0
01.12.2018, 11:51
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.12.2018, 11:51

Реализация CRUD MVC
Здравствуйте. Извиняюсь за глупый вопрос, может не правильно формулирую и вообще не о том думаю,...

Codeigniter crud и htmlspecialchars_decode
Юзаю codeigniter и crud, добавляю текстовый филд в админку, но при вводе туды &lt;meta...

CRUD для PHP
Всем привет. Поставлена задача - реализовать CRUD в табличке MySQL - возможность добавлять, менять,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru