我正在使用Sping Boot 3,Java 21 restful API和JPA with H2,我在处理事务方面遇到了问题。
我有3个控制器(用户,角色,角色)与基本的CRUD(获取,发布和删除)工作。
对于Colony
控制器,我在使用post方法创建一个新的Colony时遇到了问题。错误消息是:
无法保存菌落,原因是:无法提交JPA事务
下面是关于Colony的详细信息。
ColonyController:
@RestController
@RequestMapping("/colonies")
public class ColonyController {
ColonyService colonyService;
public ColonyController(ColonyService colonyService) {
this.colonyService = colonyService;
}
@PostMapping("")
public Colony createColony(@RequestBody Colony colony) {
return colonyService.createColony(colony);
}
}
字符串
殖民地服务:
public interface ColonyService {
public List<Colony> findAll();
public Colony createColony(Colony colony);
public Colony deleteById(String id);
public Colony findById(UUID id);
}
型
殖民地服务实施
@Component
public class ColonyServiceImpl implements ColonyService{
ColonyRepository colonyRepository;
public ColonyServiceImpl(ColonyRepository colonyRepository) {
this.colonyRepository = colonyRepository;
}
@Override
public Colony createColony(Colony colony) {
Colony newColony = null;
try {
colony.setAddresses(Collections.emptySet());
newColony = colonyRepository.save(colony);
} catch (Exception e) {
throw new ColonyRepositoryException("Failed to save colony with reason: " + e.getMessage());
}
return newColony;
}
}
型
菌落模型:
@Data
@NoArgsConstructor
@Entity
public class Colony extends Audit{
@Id
@GeneratedValue
@UuidGenerator
private UUID id;
@OneToMany(mappedBy = "colony")
private Set<Address> addresses;
@NotEmpty
private String name;
@NotEmpty
private boolean active = true;
@PrePersist
public void setCreatedAt() {
this.setCreatedAt(LocalDateTime.now());
}
}
型
地址型号:
@Data
@NoArgsConstructor
@Entity
public class Address extends Audit {
@Id
@GeneratedValue
@UuidGenerator
private UUID id;
@OneToOne(mappedBy = "address", fetch = FetchType.LAZY)
@JsonIgnore
private User user;
@ManyToOne()
@JsonIgnore
private Colony colony;
@NotEmpty
@Size(min = 3, max = 55)
private String line1;
private String line2;
private String line3;
@NotEmpty
private String postalCode;
@NotEmpty
@Size(min = 2,max = 2)
private String country; // (always required, 2 character ISO code)
@NotEmpty
private String state; // (ISO code when available)
@NotEmpty
private String city; // (City)
private String locality; //(Neighborhood / Suburb)
private String premise; // house / apt / building
@NotNull
private boolean active = true;
@PrePersist
public void setCreatedAt() {
this.setCreatedAt(LocalDateTime.now());
}
}
型
菌落储存库:
public interface ColonyRepository extends JpaRepository<Colony, UUID> {
}
型
我的 Postman 请求如下
postman request
我对请求的唯一标题是:Accept: application/json
个
JSON响应和堆栈跟踪如下:
{
"timestamp": "2024-01-02T00:27:36.124+00:00",
"status": 500,
"error": "Internal Server Error",
"trace": "com.toshi.rest.residencial.exceptions.ColonyRepositoryException: Failed to save colony with reason: Could not commit JPA transaction\n\tat com.toshi.rest.residencial.services.ColonyServiceImpl.createColony(ColonyServiceImpl.java:36)\n\tat com.toshi.rest.residencial.controllers.ColonyController.createColony(ColonyController.java:63)\n\tat java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)\n\tat java.base/java.lang.reflect.Method.invoke(Method.java:580)\n\tat org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:262)\n\tat org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:190)\n\tat org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118)\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:917)\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:829)\n\tat org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)\n\tat org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089)\n\tat org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)\n\tat org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)\n\tat org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:914)\n\tat jakarta.servlet.http.HttpServlet.service(HttpServlet.java:590)\n\tat org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)\n\tat jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)\n\tat org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)\n\tat org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)\n\tat org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)\n\tat org.springframework.web.filter.ServerHttpObservationFilter.doFilterInternal(ServerHttpObservationFilter.java:109)\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)\n\tat org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)\n\tat org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)\n\tat org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)\n\tat org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482)\n\tat org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115)\n\tat org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)\n\tat org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)\n\tat org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:340)\n\tat org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391)\n\tat org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)\n\tat org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896)\n\tat org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1744)\n\tat org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)\n\tat org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)\n\tat org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)\n\tat org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)\n\tat java.base/java.lang.Thread.run(Thread.java:1583)\n",
"message": "Failed to save colony with reason: Could not commit JPA transaction",
"path": "/colonies"
}
型
我希望发生的事情:新的条目添加到H2菌落表。
发生了什么:500响应,错误消息:“无法提交JPA事务”
任何帮助或见解将不胜感激!
堆栈跟踪:
com.toshi.rest.residencial.exceptions.ColonyRepositoryException: Failed to save colony with reason: Could not commit JPA transaction
at com.toshi.rest.residencial.services.ColonyServiceImpl.createColony(ColonyServiceImpl.java:36)
at com.toshi.rest.residencial.controllers.ColonyController.createColony(ColonyController.java:63)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:262)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:190)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:917)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:829)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:914)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:590)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
at org.springframework.web.filter.ServerHttpObservationFilter.doFilterInternal(ServerHttpObservationFilter.java:109)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:340)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1744)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:1583)
型
2条答案
按热度按时间vkc1a9a21#
错误“Could not commit JPA transaction”通常表示Spring Data JPA应用程序中transaction的提交阶段存在问题。您可以看看以下几点:Database Constraint Violation:检查Colony实体的约束(例如,@NotEmpty、@Size等)。确保您尝试保存的数据符合这些约束。如果存在约束冲突,它可能导致交易失败。检查你的输入。
字符串
以下是ColonyServiceImpl的修订版本,其中包含额外的日志记录:
型
在这个版本中,我将@ transmittance注解添加到了异常Colony方法中。此外,我还使用e.printStackTrace()添加了一个log语句来打印异常的堆栈跟踪。这可以帮助您识别问题的根本原因。
请查看上面提到的几点,并根据日志和其他信息,您可能能够查明导致事务失败的问题。
epfja78i2#
Spring(包括Sping Boot )中的@ translation annotation用于定义单个数据库事务的范围。它可以在方法级别或类级别应用。
什么时候使用@ translation:
1.数据库操作:当您有多个数据库操作需要被视为一个工作单元时。例如,考虑一个场景,您需要在一个事务中保存或更新多个实体。
1.防止不一致状态:为了确保数据一致性,特别是当多个操作需要同时成功或失败时。如果事务中的任何操作失败,@ transmittance annotation有助于回滚所有更改,防止数据库中的状态不一致。
1.默认事务配置:当在类级别应用时,服务类上的@ translation表示该类中的所有公共方法都是translational。
在您的代码中,您尝试在数据库中执行操作,因此它要求您在服务层使用**@ translation**注解(您尝试使用Repository Instance保存它)。
字符串
如果答案有效,请接受。