Непонятное поведение в спящем режиме с использованием весенних данных - PullRequest
0 голосов
/ 10 января 2020

Я просто столкнулся с действительно странным случаем, который не могу объяснить сам. У меня есть следующий сценарий:

Версия Hibernate: 5.4.9

Версия данных Spring: 2.2.3

Таким образом, следующий метод обернут в транзакцию, и это только сохраняет сущность

   @Transactional
   public Bookmark create(Entity entity) {
     return repository.save(entity);
   }

Здесь я зарегистрировал PostInsertEventListener. Основываясь на некоторых логах c, он использует тот же репозиторий для запроса базовой таблицы. Я удалил логи c, чтобы сделать пример более читабельным.

@Component
public class EntityListener implements PostInsertEventListener {

  @Autowired
  private EntityRepository repository;

  @Autowired
  private EntityManagerFactory entityManagerFactory;

  @PostConstruct
  private void init() {
    final EventListenerRegistry registry = ((SessionFactoryImplementor) entityManagerFactory.unwrap(SessionFactory.class)).getServiceRegistry()
        .getService(EventListenerRegistry.class);
    registry.appendListeners(EventType.POST_INSERT, this);
  }

  @Override
  public void onPostInsert(PostInsertEvent event) {
    if (event.getEntity() instanceof Entity) {
      repository.findByFieldOneAndFieldTwoIsNotNull(event.getEntity().fieldOne());
    }
  }

  @Override
  public boolean requiresPostCommitHanding(EntityPersister persister) {
    return false;
  }

}

Поэтому, когда я вызываю метод create(Entity entity), onPostInsert(PostInsertEvent event) запускается (как и ожидалось), но когда вызывается эта строка repository.findByFieldOneAndFieldTwoIsNotNull(event.getEntity().fieldOne()); , затем выполняется другая вставка, и onPostInsert(PostInsertEvent event) запускается снова. И, конечно, в какой-то момент это приводит к StackOverflowException.

Может кто-нибудь придумать, почему выполняется другая вставка, когда я читаю данные с использованием запроса findBy?

1 Ответ

0 голосов
/ 13 января 2020

Так что у меня есть прогресс в этом вопросе. Когда я выполняю repository.findByFieldOneAndFieldTwoIsNotNull(event.getEntity().fieldOne()); в новой отдельной транзакции, тогда все в порядке. Таким образом, кажется, что выполнение запросов в слушателе сущности в той же транзакции, в которой была выполнена вставка, приводит к бесконечной рекурсии, которая приводит к исключению StackOverflowException. Но я не могу понять, почему это происходит.

...