Мы используем Hibernate/JPA, Spring, Spring Data и Spring Безопасность в нашем приложении. У меня есть стандартный объект User
, который отображается с использованием JPA. Кроме того, у меня есть UserRepository
public interface UserRepository extends CrudRepository<User, Long> {
List<User> findByUsername(String username);
}
который следует за соглашением Spring данных для методов запроса имен. У меня есть сущность
@Entity
public class Foo extends AbstractAuditable<User, Long> {
private String name;
}
Я хочу использовать Spring поддержку аудита данных. (Как descripe здесь.) Поэтому я создал AuditorService
следующим образом:
@Service
public class AuditorService implements AuditorAware<User> {
private UserRepository userRepository;
@Override
public User getCurrentAuditor() {
String username = SecurityContextHolder.getContext().getAuthentication().getName();
List<User> users = userRepository.findByUsername(username);
if (users.size() > 0) {
return users.get(0);
} else {
throw new IllegalArgumentException();
}
}
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
}
Когда я создаю метод
@Transactional
public void createFoo() {
Foo bar = new Foo();
fooRepository.save(foo);
}
Где все правильно подключено, а FooRepository
- это Spring Данные CrudRepository
. Затем вызывается a StackOverflowError
, так как вызов findByUsername
, похоже, вызывает спящий режим для сброса данных в базу данных, которая вызывает AuditingEntityListener
, который вызывает AuditorService#getCurrentAuditor
, который снова вызывает флеш и т.д.
Как избежать этой рекурсии? Существует ли "канонический способ" для загрузки объекта User
? Или есть способ предотвратить промывание Hibernate/JPA?