У меня есть действительно неприятное исключение StackOverflowException в моем backend-сервере, с которым мне нужна помощь. Это не будет легко решено. Я действительно надеюсь найти здесь какую-то помощь.StackOverflowException в приложении spring-data-jpa с функцией Spring-security AuditorAware
Большинство частей моей внутренней работы. Я могу запросить мой интерфейс 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 интерфейс, который загружает UserModel из БД SQL. Я бы ожидал, что этот интерфейс AuditorAware вызывается только для моделей, у которых есть поле, аннотированное @CreatedBy
.
@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;
}
}
}
Сейчас я обновлю DelegationModel в моем UserRestController
. Функциональная «Scrum User Story» здесь:
Как пользователь, я хочу иметь возможность хранить делегацию, чтобы я мог передать свое право голоса на мой прокси.
@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);
[...]
}
[...]
}
По какой-то причине, что я не могу видеть, это actualy называет реализацию AuditorAware выше. Проблема в том, что моя реализация LqiuidoAuditorAware вызывается снова и снова в бесконечном цикле. Похоже, что запрос UserModel внутри LiquidoAuditorAware.java снова вызывает LiquidoAuditorAware. (Что необычно, потому что это только операция чтения из БД.)
Весь код можно найти в разделах этой github repo
Я действительно apriciate любой помогите здесь. Я ищу в темноте :-)
Большое вам спасибо за быстрый ответ! Я немного доволен, что мое первоначальное предположение было правильным, что проблема внутри AuditorAware является проблемой.Но я не видел обходного пути. Я это сделаю. – Robert
Только для справки: только что нашел этот очень похожий вопрос минуту назад: http://stackoverflow.com/questions/14223649/how-to-implement-auditoraware-with-spring-data-jpa-and-spring-security?rq = 1 – Robert