Spring Data REST / Spring Data Commons Доменные события

Я прочитал этот блог и этот справочный материал и определил, что события домена Spring Data Commons не работают при применении в событиях Spring Data REST AbstractRepositoryEventListener (т. Е. OnBeforeSave, onAfterDelete и т. Д.).

Человек:

@Entity @Data @EqualsAndHashCode(callSuper=true)
public class Person extends AbstractEntity {
  // impl

  public void markComplete(){
    registerEvent(new PersonCompletedEvent());
  }
}

PersonCompletedEvent:

@Data public class PersonCompletedEvent {} // the RestBucks sample does not have OrderPaid event extend ApplicationEvent, I tried both ways and it still doesn't work. 

Обновление: прочитайте комментарий в PersonHandler, это причина, по которой события приложения не работают в этом примере.

PersonHandler:

@Component @RepositoryEventHandler public class PersonHandler {

  @PersistenceContext private EntityManager entityManager;
  @Autowired private PersonRepo personRepo;

  @HandleBeforeSave public void beforeSave(Person afterPerson){

     /* UPDATE ::: This is the problem.
      * This line is the reason why applicatin events do not fire.
      * I need the before entity to detect delta's in the domain 
      * so I must detach it. However this causes events to be dropped.
      *
      * What's the best way to get the previous state?
      */
     entityManager.detach(afterPerson); 
     Person beforePerson = personRepo.findOne(afterPerson.getId());

     // impl
     if (some condition) {
       afterPerson.markComplete(); // this does add the event but it's never fired.
     }
  }
}

AbstractEntity:

import org.springframework.data.domain.AbstractAggregateRoot;
@MappedSuperclass @Data @EntityListeners(AuditingEntityListener.class)
public abstract class AbstractEntity extends AbstractAggregateRoot implements Identifiable<Long> {
  // impl
}

PersonListener:

public class PersonListener {
  @EventListener
  public void processCompleted(PersonCompletedEvent event) {
    // THIS IS NEVER FIRED
  }
}

Я подробно отлаживал это, и похоже, что Domain Events теряются где-то между RepositoryEntityController и EventPublishingRepositoryProxyPostProcessor$EventPublishingMethodInterceptor.

На самом деле происходит то, что другой экземпляр моей сущности фактически перехватывается, и в этот момент Domain Events больше не существует. Я могу подтвердить, что @AfterDomainEventPublication clearDomainEvents() НЕ вызывается в это время, что наводит меня на мысль, что это как-то связано с переходным процессом domainEvents.

RepositoryEntityController в Spring Data REST выглядит следующим образом:

private ResponseEntity<ResourceSupport> saveAndReturn(Object domainObject, RepositoryInvoker invoker,
            HttpMethod httpMethod, PersistentEntityResourceAssembler assembler, boolean returnBody) {

  publisher.publishEvent(new BeforeSaveEvent(domainObject));  // 1
  Object obj = invoker.invokeSave(domainObject);              // 2
  publisher.publishEvent(new AfterSaveEvent(obj));

После выполнения строки, прокомментированной с 1, мой domainObject имеет domainEvents, и это то, что входит в строку, прокомментированную с 2, invokeSave. Когда моя точка останова перехватывает RepositoryEntityController и EventPublishingRepositoryProxyPostProcessor$EventPublishingMethodInterceptor, это фактически другой экземпляр моего объекта (другой идентификатор объекта), и единственное, чего не хватает, это domainEvents и ничего не запускается.

Обновление: прочитайте мой комментарий ниже, он не работает, потому что объект отсоединен.

0 ответов

Другие вопросы по тегам