Spring-级联实体的引导验证 - 在 HttpResponse 中发送自定义错误
Spring-Boot Validation for Cascading Entity - Sending Custom Error in HttpResponse
我想发送我的自定义 ResponseEntity<> 作为我的 webService 的响应,其中包含错误的特定结构。
问题出在我的子实体上,我没有看到我正在尝试设置的自定义错误。
这些是我的 类 -
1.实体父级 (FplUser.java)
package com.tester.demojar.entities;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.validation.constraints.Size;
@Entity
@Table(name = "FPL_USER")
public class FplUser {
public FplUser() {
}
public FplUser(String userName, String userPassword, char emailVerificationStatus) {
this.emailVerificationStatus = emailVerificationStatus;
this.userName = userName;
this.userPassword = userPassword;
}
@Id
@SequenceGenerator(name = "FPL_USER_SEQ", allocationSize = 1, initialValue = 100)
@GeneratedValue(generator = "FPL_USER_SEQ", strategy = GenerationType.SEQUENCE)
@Column(name = "JPA_ID")
private long id;
@Size(min = 5, message = "UserName minimum length = 5")
@Column(name = "USER_NAME")
private String userName;
@Size(min = 8, message = "userPassword minimum length = 8")
@Column(name = "USERPASSWORD")
private String userPassword;
@Column(name = "USER_EMAIL_VERIFICATION")
private char emailVerificationStatus;
@OneToOne(cascade = {CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.REMOVE}, targetEntity = FplUserInfo.class, fetch = FetchType.LAZY, mappedBy = "fplUser")
private FplUserInfo fplUserInfo;
2。实体子 (FplUserInfo.java)
package com.tester.demojar.entities;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.validation.constraints.Min;
import javax.validation.constraints.Size;
@Entity
@Table(name = "FPL_USER_INFO")
public class FplUserInfo {
@Id
@SequenceGenerator(name = "FPL_USER_INFO_SEQ", allocationSize = 1, initialValue = 100)
@GeneratedValue(generator = "FPL_USER_INFO_SEQ", strategy = GenerationType.SEQUENCE)
@Column(name = "JPA_ID")
long jpaId;
@Min(value = 18, message = "Age should be minimum 18 Years")
@Column(name = "AGE")
int age;
@Size(min = 2, message = "favouriteTeam minimum length = 2")
@Column(name = "FAV_TEAM")
String favouriteTeam;
@JoinColumn(name = "FPL_USER_JPA_ID")
@OneToOne(cascade = {CascadeType.PERSIST, CascadeType.REFRESH}, fetch = FetchType.LAZY)
FplUser fplUser;
3。我的控制器 Class (UserRequestController.java)
package com.tester.demojar.controller;
import java.net.URI;
import java.util.List;
import java.util.Optional;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import com.tester.demojar.entities.FplUser;
import com.tester.demojar.exceptionHandling.FplUserException;
import com.tester.demojar.services.FplUserService;
@RestController
public class UserRequestController {
@Autowired
FplUserService fplUserService;
@GetMapping("/user/{jpaId}")
Optional<FplUser> getUserName(@PathVariable long jpaId) {
Optional<FplUser> fplUser = fplUserService.getDetailsOfUserName(jpaId);
System.out.println("fplUser +"+fplUser);
if(fplUser.isEmpty()) {
throw new FplUserException("id nahi mila-"+jpaId, HttpStatus.NOT_FOUND);
}
return fplUser;
}
@PostMapping("/user")
ResponseEntity<Object> insertNewUser(@Valid @RequestBody FplUser fplUser) throws FplUserException{
fplUser.getFplUserInfo().setFplUser(fplUser);
FplUser newlyAddedFplUser = fplUserService.insertNewUser(fplUser);
URI location = ServletUriComponentsBuilder.fromCurrentRequest().path("/{jpaId}").buildAndExpand(newlyAddedFplUser.getId()).toUri();
return ResponseEntity.created(location).build();
}
}
4。我的自定义异常 (FplUserException.java)
package com.tester.demojar.exceptionHandling;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
public class FplUserException extends RuntimeException {
private HttpStatus code;
public FplUserException(String message) {
super(message);
}
public FplUserException(String message, HttpStatus code) {
super(message);
this.code = code;
}
public HttpStatus getCode() {
return code;
}
}
5.我的服务响应处理异常 Class (FplAppResponseExceptionHandling.java)
package com.tester.demojar.exceptionHandling;
import java.util.Date;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
@ControllerAdvice
@RestController
public class FplAppResponseExceptionHandling extends ResponseEntityExceptionHandler{
@ExceptionHandler(FplUserException.class)
public final ResponseEntity<Object> handleUserNotFoundException(FplUserException ex, WebRequest request){
FplException fplException = new FplException(new Date(), ex.getMessage(), request.getDescription(false));
return new ResponseEntity<>(fplException, ex.getCode());
}
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(
MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
FplException fplException = new FplException(new Date(), "Validation Failed", ex.getBindingResult().toString());
return new ResponseEntity<>(fplException, HttpStatus.BAD_REQUEST);
}
}
示例测试 运行 1 \(这是预期的结果,我没看错)
输入-
{
"userName": "A4",
"userPassword": "randomePass",
"emailVerificationStatus": "N",
"fplUserInfo":{
"age":"19",
"favouriteTeam":"RealMadrid"
}
}
预期输出 - 我的回复应该是用户名大小应该大于 5
我的实际输出 -
{
"timestamp": "2021-05-31T10:23:46.928+00:00",
"message": "Validation Failed",
"details": "org.springframework.validation.BeanPropertyBindingResult: 1 errors\nField error in object 'fplUser' on field 'userName': rejected value [A4]; codes [Size.fplUser.userName,Size.userName,Size.java.lang.String,Size]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [fplUser.userName,userName];
arguments []; default message [userName],2147483647,5]; default message [UserName minimum length = 5]"
}
Image - 这是预期的,我得到了我的 Parent 实体的预期响应
示例测试 运行 2 \(这不是预期的结果,我弄错了)
输入-
{
"userName": "A4truth",
"userPassword": "randomePass",
"emailVerificationStatus": "N",
"fplUserInfo":{
"age":"16",
"favouriteTeam":"RealMadrid"
}
}
预期产出 - 我的回复应该是“年龄至少应年满 18 岁” 并给出 HTTP Bad request 400
我的实际输出 -
{
"timestamp": "2021-05-31T10:34:30.959+00:00",
"status": 500,
"error": "Internal Server Error",
"trace": "org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction\r\n\tat org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:571)\r\n\tat org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:743)\r\n\tat org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:711)\r\n\tat org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:654)\r\n\tat org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:407)\r\n\tat org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)\r\n\tat org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\r\n\tat org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)\r\n\tat org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\r\n\tat org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:174)\r\n\tat org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\r\n\tat org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)\r\n\tat org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\r\n\tat org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215)\r\n\tat com.sun.proxy.$Proxy237.save(Unknown Source)\r\n\tat com.tester.demojar.services.FplUserService.insertNewUser(FplUserService.java:31)\r\n\tat com.tester.demojar.controller.UserRequestController.insertNewUser(UserRequestController.java:52)\r\n\tat java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\r\n\tat java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\r\n\tat java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\r\n\tat java.base/java.lang.reflect.Method.invoke(Method.java:566)\r\n\tat org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:197)\r\n\tat org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:141)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)\r\n\tat org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)\r\n\tat org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1063)\r\n\tat org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)\r\n\tat org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)\r\n\tat org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)\r\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:652)\r\n\tat org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)\r\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:733)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\r\n\tat org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\r\n\tat org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\r\n\tat org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\r\n\tat org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:92)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\r\n\tat org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\r\n\tat org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)\r\n\tat org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)\r\n\tat org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)\r\n\tat org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)\r\n\tat org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)\r\n\tat org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)\r\n\tat org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)\r\n\tat org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)\r\n\tat org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)\r\n\tat org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893)\r\n\tat org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707)\r\n\tat org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)\r\n\tat java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)\r\n\tat java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)\r\n\tat org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)\r\n\tat java.base/java.lang.Thread.run(Thread.java:834)\r\nCaused by: javax.persistence.RollbackException: Error while committing the transaction\r\n\tat org.hibernate.internal.ExceptionConverterImpl.convertCommitException(ExceptionConverterImpl.java:81)\r\n\tat org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:104)\r\n\tat org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:562)\r\n\t... 70 more\r\nCaused by: javax.validation.ConstraintViolationException: Validation failed for classes [com.tester.demojar.entities.FplUserInfo] during persist time for groups [javax.validation.groups.Default, ]\nList of constraint violations:[\n\tConstraintViolationImpl{interpolatedMessage='Age should be minimum 18 Years', propertyPath=age, rootBeanClass=class com.tester.demojar.entities.FplUserInfo, messageTemplate='Age should be minimum 18 Years'}\n]\r\n\tat org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:140)\r\n\tat org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreInsert(BeanValidationEventListener.java:80)\r\n\tat org.hibernate.action.internal.EntityInsertAction.preInsert(EntityInsertAction.java:214)\r\n\tat org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:100)\r\n\tat org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604)\r\n\tat org.hibernate.engine.spi.ActionQueue.lambda$executeActions(ActionQueue.java:478)\r\n\tat java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:684)\r\n\tat org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:475)\r\n\tat org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:345)\r\n\tat org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:40)\r\n\tat org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:93)\r\n\tat org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1362)\r\n\tat org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:453)\r\n\tat org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3212)\r\n\tat org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2380)\r\n\tat org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:447)\r\n\tat org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:183)\r\n\tat org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access0(JdbcResourceLocalTransactionCoordinatorImpl.java:40)\r\n\tat org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:281)\r\n\tat org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:101)\r\n\t... 71 more\r\n",
"message": "Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction",
"path": "/user"
}
图片 - 这不是预期的
图片
感谢任何帮助!!
所以我错过了将 @valid
添加到 属性。
我们应该将 @valid 添加到级联 属性.
private FplUserInfo fplUserInfo;
在 FplUser.java class.
早些时候-
@OneToOne(cascade = {CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.REMOVE}, targetEntity = FplUserInfo.class, fetch = FetchType.LAZY, mappedBy = "fplUser")
private FplUserInfo fplUserInfo;
更正 -
@Valid
@OneToOne(cascade = {CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.REMOVE}, targetEntity = FplUserInfo.class, fetch = FetchType.LAZY, mappedBy = "fplUser")
private FplUserInfo fplUserInfo;
我想发送我的自定义 ResponseEntity<> 作为我的 webService 的响应,其中包含错误的特定结构。
问题出在我的子实体上,我没有看到我正在尝试设置的自定义错误。
这些是我的 类 -
1.实体父级 (FplUser.java)
package com.tester.demojar.entities;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.validation.constraints.Size;
@Entity
@Table(name = "FPL_USER")
public class FplUser {
public FplUser() {
}
public FplUser(String userName, String userPassword, char emailVerificationStatus) {
this.emailVerificationStatus = emailVerificationStatus;
this.userName = userName;
this.userPassword = userPassword;
}
@Id
@SequenceGenerator(name = "FPL_USER_SEQ", allocationSize = 1, initialValue = 100)
@GeneratedValue(generator = "FPL_USER_SEQ", strategy = GenerationType.SEQUENCE)
@Column(name = "JPA_ID")
private long id;
@Size(min = 5, message = "UserName minimum length = 5")
@Column(name = "USER_NAME")
private String userName;
@Size(min = 8, message = "userPassword minimum length = 8")
@Column(name = "USERPASSWORD")
private String userPassword;
@Column(name = "USER_EMAIL_VERIFICATION")
private char emailVerificationStatus;
@OneToOne(cascade = {CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.REMOVE}, targetEntity = FplUserInfo.class, fetch = FetchType.LAZY, mappedBy = "fplUser")
private FplUserInfo fplUserInfo;
2。实体子 (FplUserInfo.java)
package com.tester.demojar.entities;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.validation.constraints.Min;
import javax.validation.constraints.Size;
@Entity
@Table(name = "FPL_USER_INFO")
public class FplUserInfo {
@Id
@SequenceGenerator(name = "FPL_USER_INFO_SEQ", allocationSize = 1, initialValue = 100)
@GeneratedValue(generator = "FPL_USER_INFO_SEQ", strategy = GenerationType.SEQUENCE)
@Column(name = "JPA_ID")
long jpaId;
@Min(value = 18, message = "Age should be minimum 18 Years")
@Column(name = "AGE")
int age;
@Size(min = 2, message = "favouriteTeam minimum length = 2")
@Column(name = "FAV_TEAM")
String favouriteTeam;
@JoinColumn(name = "FPL_USER_JPA_ID")
@OneToOne(cascade = {CascadeType.PERSIST, CascadeType.REFRESH}, fetch = FetchType.LAZY)
FplUser fplUser;
3。我的控制器 Class (UserRequestController.java)
package com.tester.demojar.controller;
import java.net.URI;
import java.util.List;
import java.util.Optional;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import com.tester.demojar.entities.FplUser;
import com.tester.demojar.exceptionHandling.FplUserException;
import com.tester.demojar.services.FplUserService;
@RestController
public class UserRequestController {
@Autowired
FplUserService fplUserService;
@GetMapping("/user/{jpaId}")
Optional<FplUser> getUserName(@PathVariable long jpaId) {
Optional<FplUser> fplUser = fplUserService.getDetailsOfUserName(jpaId);
System.out.println("fplUser +"+fplUser);
if(fplUser.isEmpty()) {
throw new FplUserException("id nahi mila-"+jpaId, HttpStatus.NOT_FOUND);
}
return fplUser;
}
@PostMapping("/user")
ResponseEntity<Object> insertNewUser(@Valid @RequestBody FplUser fplUser) throws FplUserException{
fplUser.getFplUserInfo().setFplUser(fplUser);
FplUser newlyAddedFplUser = fplUserService.insertNewUser(fplUser);
URI location = ServletUriComponentsBuilder.fromCurrentRequest().path("/{jpaId}").buildAndExpand(newlyAddedFplUser.getId()).toUri();
return ResponseEntity.created(location).build();
}
}
4。我的自定义异常 (FplUserException.java)
package com.tester.demojar.exceptionHandling;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
public class FplUserException extends RuntimeException {
private HttpStatus code;
public FplUserException(String message) {
super(message);
}
public FplUserException(String message, HttpStatus code) {
super(message);
this.code = code;
}
public HttpStatus getCode() {
return code;
}
}
5.我的服务响应处理异常 Class (FplAppResponseExceptionHandling.java)
package com.tester.demojar.exceptionHandling;
import java.util.Date;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
@ControllerAdvice
@RestController
public class FplAppResponseExceptionHandling extends ResponseEntityExceptionHandler{
@ExceptionHandler(FplUserException.class)
public final ResponseEntity<Object> handleUserNotFoundException(FplUserException ex, WebRequest request){
FplException fplException = new FplException(new Date(), ex.getMessage(), request.getDescription(false));
return new ResponseEntity<>(fplException, ex.getCode());
}
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(
MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
FplException fplException = new FplException(new Date(), "Validation Failed", ex.getBindingResult().toString());
return new ResponseEntity<>(fplException, HttpStatus.BAD_REQUEST);
}
}
示例测试 运行 1 \(这是预期的结果,我没看错) 输入-
{
"userName": "A4",
"userPassword": "randomePass",
"emailVerificationStatus": "N",
"fplUserInfo":{
"age":"19",
"favouriteTeam":"RealMadrid"
}
}
预期输出 - 我的回复应该是用户名大小应该大于 5
我的实际输出 -
{
"timestamp": "2021-05-31T10:23:46.928+00:00",
"message": "Validation Failed",
"details": "org.springframework.validation.BeanPropertyBindingResult: 1 errors\nField error in object 'fplUser' on field 'userName': rejected value [A4]; codes [Size.fplUser.userName,Size.userName,Size.java.lang.String,Size]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [fplUser.userName,userName];
arguments []; default message [userName],2147483647,5]; default message [UserName minimum length = 5]"
}
Image - 这是预期的,我得到了我的 Parent 实体的预期响应
示例测试 运行 2 \(这不是预期的结果,我弄错了) 输入-
{
"userName": "A4truth",
"userPassword": "randomePass",
"emailVerificationStatus": "N",
"fplUserInfo":{
"age":"16",
"favouriteTeam":"RealMadrid"
}
}
预期产出 - 我的回复应该是“年龄至少应年满 18 岁” 并给出 HTTP Bad request 400
我的实际输出 -
{
"timestamp": "2021-05-31T10:34:30.959+00:00",
"status": 500,
"error": "Internal Server Error",
"trace": "org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction\r\n\tat org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:571)\r\n\tat org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:743)\r\n\tat org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:711)\r\n\tat org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:654)\r\n\tat org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:407)\r\n\tat org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)\r\n\tat org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\r\n\tat org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)\r\n\tat org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\r\n\tat org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:174)\r\n\tat org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\r\n\tat org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)\r\n\tat org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\r\n\tat org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215)\r\n\tat com.sun.proxy.$Proxy237.save(Unknown Source)\r\n\tat com.tester.demojar.services.FplUserService.insertNewUser(FplUserService.java:31)\r\n\tat com.tester.demojar.controller.UserRequestController.insertNewUser(UserRequestController.java:52)\r\n\tat java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\r\n\tat java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\r\n\tat java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\r\n\tat java.base/java.lang.reflect.Method.invoke(Method.java:566)\r\n\tat org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:197)\r\n\tat org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:141)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)\r\n\tat org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)\r\n\tat org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1063)\r\n\tat org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)\r\n\tat org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)\r\n\tat org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)\r\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:652)\r\n\tat org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)\r\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:733)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\r\n\tat org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\r\n\tat org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\r\n\tat org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\r\n\tat org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:92)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\r\n\tat org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\r\n\tat org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)\r\n\tat org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)\r\n\tat org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)\r\n\tat org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)\r\n\tat org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)\r\n\tat org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)\r\n\tat org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)\r\n\tat org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)\r\n\tat org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)\r\n\tat org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893)\r\n\tat org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707)\r\n\tat org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)\r\n\tat java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)\r\n\tat java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)\r\n\tat org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)\r\n\tat java.base/java.lang.Thread.run(Thread.java:834)\r\nCaused by: javax.persistence.RollbackException: Error while committing the transaction\r\n\tat org.hibernate.internal.ExceptionConverterImpl.convertCommitException(ExceptionConverterImpl.java:81)\r\n\tat org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:104)\r\n\tat org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:562)\r\n\t... 70 more\r\nCaused by: javax.validation.ConstraintViolationException: Validation failed for classes [com.tester.demojar.entities.FplUserInfo] during persist time for groups [javax.validation.groups.Default, ]\nList of constraint violations:[\n\tConstraintViolationImpl{interpolatedMessage='Age should be minimum 18 Years', propertyPath=age, rootBeanClass=class com.tester.demojar.entities.FplUserInfo, messageTemplate='Age should be minimum 18 Years'}\n]\r\n\tat org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:140)\r\n\tat org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreInsert(BeanValidationEventListener.java:80)\r\n\tat org.hibernate.action.internal.EntityInsertAction.preInsert(EntityInsertAction.java:214)\r\n\tat org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:100)\r\n\tat org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604)\r\n\tat org.hibernate.engine.spi.ActionQueue.lambda$executeActions(ActionQueue.java:478)\r\n\tat java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:684)\r\n\tat org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:475)\r\n\tat org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:345)\r\n\tat org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:40)\r\n\tat org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:93)\r\n\tat org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1362)\r\n\tat org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:453)\r\n\tat org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3212)\r\n\tat org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2380)\r\n\tat org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:447)\r\n\tat org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:183)\r\n\tat org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access0(JdbcResourceLocalTransactionCoordinatorImpl.java:40)\r\n\tat org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:281)\r\n\tat org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:101)\r\n\t... 71 more\r\n",
"message": "Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction",
"path": "/user"
}
图片 - 这不是预期的
图片
感谢任何帮助!!
所以我错过了将 @valid
添加到 属性。
我们应该将 @valid 添加到级联 属性.
private FplUserInfo fplUserInfo;
在 FplUser.java class.
早些时候-
@OneToOne(cascade = {CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.REMOVE}, targetEntity = FplUserInfo.class, fetch = FetchType.LAZY, mappedBy = "fplUser")
private FplUserInfo fplUserInfo;
更正 -
@Valid
@OneToOne(cascade = {CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.REMOVE}, targetEntity = FplUserInfo.class, fetch = FetchType.LAZY, mappedBy = "fplUser")
private FplUserInfo fplUserInfo;