【发布时间】:2017-07-08 01:03:24
【问题描述】:
我的 Spring 后端有一个非常讨厌的 StackOverflowException,我需要帮助。这不会轻易解决。我真的希望能在这里找到一些帮助。
我的大部分后端工作。我可以在我的 REST 接口中查询模型,它们很好地由 spring-hateoas、GET、PUT 和 POST 操作返回。但有一个例外:当我尝试更新现有的 DelegationModel 时,我遇到了无休止的 StackOverflowException。
这是我的DelegetionModel.java 课程。请注意,该委托模型实际上没有任何带有 @CreatedBy 注释的属性!
@Entity
@Data
@NoArgsConstructor
@RequiredArgsConstructor(suppressConstructorProperties = true) //BUGFIX: https://jira.spring.io/browse/DATAREST-884
@EntityListeners(AuditingEntityListener.class) // this is necessary so that UpdatedAt and CreatedAt are handled.
@Table(name = "delegations")
public class DelegationModel {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Long id;
/** Area that this delegation is in */
@NonNull
@NotNull
@ManyToOne
public AreaModel area;
/** reference to delegee that delegated his vote */
@NonNull
@NotNull
@ManyToOne
public UserModel fromUser;
/** reference to proxy that receives the delegation */
@NonNull
@NotNull
@ManyToOne
public UserModel toProxy;
@CreatedDate
@NotNull
public Date createdAt = new Date();
@LastModifiedDate
@NotNull
public Date updatedAt = new Date();
}
如Spring-data-jpa doc 中所述,我实现了必要的 AuditorAware 接口,该接口从 SQL DB 加载 UserModel。我原以为只有字段用@CreatedBy 注释的模型才会调用此 AuditorAware 接口。
@Component
public class LiquidoAuditorAware implements AuditorAware<UserModel> {
Logger log = LoggerFactory.getLogger(this.getClass()); // Simple Logging Facade 4 Java
@Autowired
UserRepo userRepo;
@Override
public UserModel getCurrentAuditor() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null || !authentication.isAuthenticated()) {
log.warn("Cannot getCurrentAuditor. No one is currently authenticated");
return null;
}
User principal = (org.springframework.security.core.userdetails.User) authentication.getPrincipal();
UserModel currentlyLoggedInUser = userRepo.findByEmail(principal.getUsername()); // <<<<======= (!)
return currentlyLoggedInUser;
} catch (Exception e) {
log.error("Cannot getCurrentAuditor: "+e);
return null;
}
}
}
现在我在UserRestController 中更新了一个DelegationModel。这里的功能性“Scrum 用户故事”是:
作为用户,我希望能够存储一个委托,以便我可以将我的投票权转发给我的代理。
@RestController
@RequestMapping("/liquido/v2/users")
public class UserRestController {
[...]
@RequestMapping(value = "/saveProxy", method = PUT, consumes="application/json")
@ResponseStatus(HttpStatus.CREATED)
public @ResponseBody String saveProxy(
@RequestBody Resource<DelegationModel> delegationResource,
//PersistentEntityResourceAssembler resourceAssembler,
Principal principal) throws BindException
{
[...]
DelegationModel result = delegationRepo.save(existingDelegation);
[...]
}
[...]
}
由于某种原因,我看不到,这实际上调用了上面的 AuditorAware 实现。现在的问题是,我的 LqiuidoAuditorAware 实现在无限循环中被一次又一次地调用。似乎 LiquidoAuditorAware.java 中对 UserModel 的查询再次调用了 LiquidoAuditorAware。 (这很不寻常,因为这只是从数据库读取操作。)
所有代码都可以在github repo中找到
我真的很想在这里得到任何帮助。我在黑暗中寻找:-)
【问题讨论】:
标签: spring-security spring-data spring-data-jpa