TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException:
При добавлении валидации вводимых данных в дочернюю Entity(MobileHome) выбрасывается исключение, самостоятельно разобраться с данной ситуацией не получается. Исключение выбрасывается при вводе или исправлении данных(не соответствующих @Pattern) в форму mobileHome. В родительской Entity(Person) валидация проходит успешно, с выводом в jsp сообщения об ошибке.
org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:526) ~[spring-orm-4.0.9.RELEASE.jar:4.0.9.RELEASE] at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:757) ~[spring-tx-4.0.9.RELEASE.jar:4.0.9.RELEASE] at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:726) ~[spring-tx-4.0.9.RELEASE.jar:4.0.9.RELEASE] at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:478) ~[spring-tx-4.0.9.RELEASE.jar:4.0.9.RELEASE] at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:272) ~[spring-tx-4.0.9.RELEASE.jar:4.0.9.RELEASE] at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95) ~[spring-tx-4.0.9.RELEASE.jar:4.0.9.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207) ~[spring-aop-4.2.0.RELEASE.jar:4.2.0.RELEASE] at com.sun.proxy.$Proxy38.savePerson(Unknown Source) ~[na:na] at com.infinitivus.project.controllers.PersonController.savePerson(PersonController.java:52) ~[classes/:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na] at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) ~[spring-web-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) ~[spring-web-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:111) ~[spring-webmvc-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:806) ~[spring-webmvc-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:729) ~[spring-webmvc-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) ~[spring-webmvc-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) ~[spring-webmvc-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) ~[spring-webmvc-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872) ~[spring-webmvc-4.2.0.RELEASE.jar:4.2.0.RELEASE] at javax.servlet.http.HttpServlet.service(HttpServlet.java:681) ~[servlet-api.jar:4.0.FR] at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) ~[spring-webmvc-4.2.0.RELEASE.jar:4.2.0.RELEASE] at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) ~[servlet-api.jar:4.0.FR] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[catalina.jar:9.0.54] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[catalina.jar:9.0.54] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-websocket.jar:9.0.54] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[catalina.jar:9.0.54] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[catalina.jar:9.0.54] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[catalina.jar:9.0.54] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[catalina.jar:9.0.54] at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540) ~[catalina.jar:9.0.54] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) ~[catalina.jar:9.0.54] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[catalina.jar:9.0.54] at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687) ~[catalina.jar:9.0.54] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[catalina.jar:9.0.54] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) ~[catalina.jar:9.0.54] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382) ~[tomcat-coyote.jar:9.0.54] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-coyote.jar:9.0.54] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:895) ~[tomcat-coyote.jar:9.0.54] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1722) ~[tomcat-coyote.jar:9.0.54] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-coyote.jar:9.0.54] at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-util.jar:9.0.54] at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-util.jar:9.0.54] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-util.jar:9.0.54] at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na] Caused by: javax.persistence.RollbackException: Error while committing the transaction at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:94) ~[hibernate-entitymanager-4.3.11.Final.jar:4.3.11.Final] at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:517) ~[spring-orm-4.0.9.RELEASE.jar:4.0.9.RELEASE] ... 48 common frames omitted Caused by: javax.validation.ConstraintViolationException: Validation failed for classes [com.infinitivus.project.entity.person_entity.MobileHome] during update time for groups [javax.validation.groups.Default, ] List of constraint violations:[ ConstraintViolationImpl{interpolatedMessage='Error! Enter the sample data', propertyPath=type, rootBeanClass=class com.infinitivus.project.entity.person_entity.MobileHome, messageTemplate='Error! Enter the sample data'} ] at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:160) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreUpdate(BeanValidationEventListener.java:103) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] at org.hibernate.action.internal.EntityUpdateAction.preUpdate(EntityUpdateAction.java:257) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] at org.hibernate.action.internal.EntityUpdateAction.execute(EntityUpdateAction.java:134) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:465) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:351) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:350) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:56) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1258) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:425) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:177) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:77) ~[hibernate-entitymanager-4.3.11.Final.jar:4.3.11.Final] ... 49 common frames omitted
Controller:
package com.infinitivus.project.controllers;
import com.infinitivus.project.entity.person_entity.MobileHome;
import com.infinitivus.project.entity.person_entity.Person;
import com.infinitivus.project.servace.person_service.IPersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import javax.validation.Valid;
import java.util.List;
@Controller
public class PersonController {
@Autowired
private IPersonService iPersonService;
@RequestMapping(value = {"/"})
public String showAllPerson(Model model) {
List<Person> allPerson = iPersonService.allPerson();
model.addAttribute("allPers", allPerson);
return "view_person/show_all_person";
}
//-------------------------------------------------------------
// Не работает валидация class MobileHome.
@RequestMapping("/addNewPersonData")
public String addNewPersonData(Model model) {
model.addAttribute("person",new Person());
model.addAttribute("mobileHome",new MobileHome());
return "view_person/add_new_person_data";
}
@RequestMapping("/savePersonData")
public String savePerson(@Valid @ModelAttribute("person") Person person, BindingResult bindingPerson,
@Valid @ModelAttribute("mobileHome") MobileHome mobileHome,BindingResult bindingMobileHome)
{
if (bindingPerson.hasErrors()
|| bindingMobileHome.hasErrors())
{
return "view_person/add_new_person_data";
} else {
iPersonService.savePerson(person);
return "redirect:/";
}
}
//-----------------------------------------------------------------------------------------------------
@RequestMapping("/fullInfoPerson")
public String fullInfoPerson(@RequestParam("infoPersId") Integer id, Model model) {
Person person = iPersonService.getPerson(id);
model.addAttribute("pers", person);
return "view_person/full_info_person";
}
@RequestMapping("/updateInfoPerson")
public String updatePerson(@RequestParam("infoPersId") Integer id, Model model) {
Person person = iPersonService.getPerson(id);
model.addAttribute("person", person);
return "view_person/add_new_person_data";
}
@RequestMapping("/deleteInfoPerson")
public String deletePerson(@RequestParam("infoPersId") Integer id) {
iPersonService.deletePerson(id);
return "redirect:/";
}
@RequestMapping("/searchPerson")
public String searchPerson(@RequestParam("search") String searchLine, Model model) {
List<Person> searchListPerson = iPersonService.searchPerson(searchLine);
model.addAttribute("allPers", searchListPerson);
return "view_person/show_all_person";
}
@RequestMapping("/sortPerson")
public String sortPerson(@RequestParam("select") String sortLine, Model model) {
List<Person> sortListPerson = iPersonService.sortPerson(sortLine);
model.addAttribute("allPers", sortListPerson);
return "view_person/show_all_person";
}
}
Entity:
package com.infinitivus.project.entity.person_entity;
import javax.persistence.*;
import javax.validation.constraints.Pattern;
@Entity
@Table(name = "person")
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Integer id;
@Column(name = "surname")
@Pattern(regexp = "^([А-Яа-яЁё]|[A-Za-z]){3,15}$", message = "Error! Enter the sample data")
private String surname;
@Column(name = "name")
@Pattern(regexp = "^[A-Za-zА-Яа-яёЁ]{3,15}\\s?([A-Za-zА-Яа-яёЁ]{3,15})?$", message = "Error! Enter the sample data")
private String name;
@Column(name = "phone_number")
@Pattern(regexp = "^((8|\\+7)[\\-]?)?(\\(?\\d{3}\\)?[\\- ]?)?[\\d\\- ]{7,10}$", message = "Error! Enter the sample data")
private String phoneNumber;
@Column(name = "email")
@Pattern(regexp = "^(\\w+@\\w+\\.(com|ru))?$", message = "Error! Enter the sample data")
private String email;
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
@JoinColumn(name = "mobile_home_id")
private MobileHome mobileHome;
public Person() {
}
public Person(String surname, String name, String phoneNumber, String email) {
this.surname = surname;
this.name = name;
this.phoneNumber = phoneNumber;
this.email = email;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public MobileHome getMobileHome() {
return mobileHome;
}
public void setMobileHome(MobileHome mobileHome) {
this.mobileHome = mobileHome;
}
@Override
public String toString() {
return "Person{" +
"id=" + id +
", surname='" + surname + '\'' +
", name='" + name + '\'' +
", phoneNumber='" + phoneNumber + '\'' +
", email='" + email + '\'' +
", mobileHome=" + mobileHome +
'}';
}
}
package com.infinitivus.project.entity.person_entity;
import javax.persistence.*;
import javax.validation.constraints.Pattern;
@Entity
@Table(name = "mobile_home")
public class MobileHome {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Integer id;
@Column(name = "type")
@Pattern(regexp = "^(([А-Яа-яЁё]|[A-Za-z]){3,15})?$", message = "Error! Enter the sample data")
private String type;
@Column(name = "brand")
@Pattern(regexp = "^(([А-Яа-яЁё]|[A-Za-z]){3,15})?$", message = "Error! Enter the sample data")
private String brand;
@Column(name = "model")
@Pattern(regexp = "^(([А-Яа-яЁё]|[A-Za-z]){3,15})?$", message = "Error! Enter the sample data")
private String model;
@OneToOne(mappedBy = "mobileHome")
private Person homePerson;
public MobileHome() {
}
public MobileHome(String type, String brand, String model, Person homePerson) {
this.type = type;
this.brand = brand;
this.model = model;
this.homePerson = homePerson;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public Person getHomePerson() {
return homePerson;
}
public void setHomePerson(Person homePerson) {
this.homePerson = homePerson;
}
@Override
public String toString() {
return "MobileHome{" +
"id=" + id +
", type='" + type + '\'' +
", brand='" + brand + '\'' +
", model='" + model + '\'' +
", homePerson=" + homePerson +
'}';
}
}
Service:
package com.infinitivus.project.servace.person_service;
import com.infinitivus.project.entity.person_entity.Person;
import java.util.List;
public interface IPersonService {
List<Person> allPerson();
void savePerson(Person person);
Person getPerson(Integer id);
void deletePerson(Integer id);
List<Person> searchPerson(String searchLine);
List<Person> sortPerson(String sortLine);
}
package com.infinitivus.project.servace.person_service;
import com.infinitivus.project.dao.person_dao.IPersonRepository;
import com.infinitivus.project.entity.person_entity.Person;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class PersonServiceImpl implements IPersonService {
@Autowired
private IPersonRepository iPersonRepository;
@Override
@Transactional
public List<Person> allPerson() {
return iPersonRepository.getAllPerson();
}
@Override
@Transactional
public void savePerson(Person person) {
iPersonRepository.savePerson(person);
}
@Override
@Transactional
public Person getPerson(Integer id) {
return iPersonRepository.getPerson(id);
}
@Override
@Transactional
public void deletePerson(Integer id) {
iPersonRepository.deletePerson(id);
}
@Override
@Transactional
public List<Person> searchPerson(String searchLine) {
return iPersonRepository.searchPerson(searchLine);
}
@Override
@Transactional
public List<Person> sortPerson(String sortLine) {
return iPersonRepository.sortPerson(sortLine);
}
}
JSP:
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" \>
<title>add_update data</title>
</head>
<c:url var="backToList" value="/"/>
<body>
<br>
<table align="center" width="90%">
<tr>
<td align="left"><input type="button" value="<- Back to the list"
onclick="window.location.href='${backToList}'"/></td>
</tr>
</table>
<form:form action="savePersonData" modelAttribute="person">
<form:hidden path="id"/>
<h3 align="center">Add or edit information</h3>
<table align="center" width="90%">
<h4 align="center">Personal information</h4>
<tr>
<td align="center">Last name from 3 to 15 letters</td>
<td align="center">First name from 3 to 30 letters</td>
<td align="center">phone number-sample:89011234567</td>
<td align="center">email-sample:[email protected]</td>
</tr>
<tr>
<td align="center"><form:input path="surname" placeholder="Surname:required"/></td>
<td align="center"><form:input path="name" placeholder="Name:required"/></td>
<td align="center"><form:input path="phoneNumber" placeholder="Phone number:required"/></td>
<td align="center"><form:input path="email" placeholder="Email:optional"/></td>
</tr>
<tr>
<td align="center"><form:errors cssStyle="color: red" path="surname"/></td>
<td align="center"><form:errors cssStyle="color: red" path="name"/></td>
<td align="center"><form:errors cssStyle="color: red" path="phoneNumber"/></td>
<td align="center"><form:errors cssStyle="color: red" path="email"/></td>
</tr>
</table>
<table align="center" width="90%">
<h4 align="center">Motorhome information</h4>
<form:hidden path="mobileHome.id"/>
<tr>
<td align="center">Type from 3 to 15 letters</td>
<td align="center">Brand from 3 to 15 letters</td>
<td align="center">Model from 3 to 15 letters</td>
</tr>
<tr>
<td align="center"><form:input path="mobileHome.type" placeholder="Type:optional"/></td>
<td align="center"><form:input path="mobileHome.brand" placeholder="Brand:optional"/></td>
<td align="center"><form:input path="mobileHome.model" placeholder="Model:optional"/></td>
</tr>
<tr>
<td align="center"><form:errors cssStyle="color: red" path="mobileHome.type"/></td>
<td align="center"><form:errors cssStyle="color: red" path="mobileHome.brand"/></td>
<td align="center"><form:errors cssStyle="color: red" path="mobileHome.model"/></td>
</tr>
</table>
<br>
<table align="center" width="90%">
<tr>
<td align="left"><input type="submit" value="Save"
onclick="window.location.href='${savePersonData}'"/></td>
</tr>
</table>
</form:form>
</body>
</html>
Полностью код доступен на GitHub: https://github.com/infinitivus/spring_mvc_customer_base
Буду очень признателен за любую помощь