我有一个票证对象,应该对其进行编辑。在我的票证对象中有引用对象的属性(请参见下文)。
...
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "project_id", referencedColumnName="id")
private Project project;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "costCenter_id", referencedColumnName="id")
private CostCenter costCenter;
...
但是当我尝试更新实体时,总是会出现错误:
无法提交JPA交易;嵌套的异常是javax.persistence.RollbackException:提交事务时出错
@PutMapping("/tickets/{id}")
@ResponseStatus(HttpStatus.OK)
public Ticket updateTicket(@RequestBody Ticket ticket) throws Exception{
Optional<Ticket> o = this.ticketRepo.findById(ticket.getId());
o.ifPresent(element -> {
if(ticket.getCostCenter() != null) {
Optional<CostCenter> c = this.costCenterRepo.findById(ticket.getCostCenter().getId());
c.ifPresent( costCenter -> {
element.setCostCenter(costCenter);
});
}
if(ticket.getProject() != null) {
Optional<Project> p = this.projectRepo.findById(ticket.getProject().getId());
p.ifPresent(project -> {
element.setProject(project);
});
}
this.ticketRepo.save(element);
});
return o.orElseThrow(() -> new NotFoundException(ticket.getId()));
}
PS:当我触发更新而不进行任何更改时,一切正常。
Stacktrace:https://textsaver.flap.tv/lists/2vm5
class AuditorAwareImpl implements AuditorAware<Long> {
@Override
public Optional<Long> getCurrentAuditor() {
PersonRepository personRepo = ApplicationContextProvider.getApplicationContext().getBean(PersonRepository.class);
if(SecurityContextHolder.getContext().getAuthentication() != null) {
Person p = personRepo.findByUserPrincipalName(SecurityContextHolder.getContext().getAuthentication().getName() + "@email.com");
return Optional.of(p.getId());
} else {
Person p = personRepo.findByUserPrincipalName("SYSTEM");
return Optional.of(p.getId());
}
}
}
@Component(value = "applicationContextProvider")
class ApplicationContextProvider implements ApplicationContextAware {
private static class AplicationContextHolder {
private static final InnerContextResource CONTEXT_PROV = new InnerContextResource();
}
private static final class InnerContextResource {
private ApplicationContext context;
private void setContext(ApplicationContext context) {
this.context = context;
}
}
public static ApplicationContext getApplicationContext() {
return AplicationContextHolder.CONTEXT_PROV.context;
}
@Override
public void setApplicationContext(ApplicationContext ac) {
AplicationContextHolder.CONTEXT_PROV.setContext(ac);
}
}
@Data
@Getter
@Setter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class BaseEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", updatable = false, nullable = false)
protected Long id;
@CreatedDate
private Date createdAt;
@CreatedBy
private Long createdBy;
@LastModifiedDate
private Date updatedAt;
@LastModifiedBy
private Long updatedBy;
@PrePersist
protected void prePersist() {
if (this.createdAt == null) createdAt = new Date();
if (this.updatedAt == null) updatedAt = new Date();
}
@PreUpdate
protected void preUpdate() {
this.updatedAt = new Date();
}
@PreRemove
protected void preRemove() {
this.updatedAt = new Date();
}
}
答案 0 :(得分:4)
您有一个StackOverflowError
,强烈建议您在某处(或至少是一个很深的地方)进行了无限递归:
Caused by: java.lang.RuntimeException: java.lang.StackOverflowError
com.mycompany.test.config.AuditorAwareImpl.getCurrentAuditor
在您很长的堆栈跟踪中反复出现的事实表明,它以某种方式参与了您的无限递归,我敢打赌,它是由此类引发的,无论如何首先触发了它可能org.springframework.data.auditing.AuditingHandler
。因此,请检查您的AuditorAwareImpl
代码和/或审核配置。