1

我阅读了此博客和此参考资料,并确定在 Spring Data REST AbstractRepositoryEventListener 事件(即 onBeforeSave、onAfterDelete 等)中应用 Spring Data Commons Domain Events 时不起作用。

人:

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

  public void markComplete(){
    registerEvent(new 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. 

更新:阅读 PersonH​​andler 中的注释,这就是为什么应用程序事件在此示例中不起作用的原因。

人员处理程序:

@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.
     }
  }
}

抽象实体:

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

个人监听器:

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

我已经对此进行了广泛的调试,看起来 DomainEvents 被丢弃在RepositoryEntityControllerEventPublishingRepositoryProxyPostProcessor$EventPublishingMethodInterceptor之间的某个地方。

真正发生的是,我的 Entity 的另一个实例实际上被拦截了,此时 DomainEvents 不再存在。我可以确认此时没有调用 @AfterDomainEventPublication clearDomainEvents(),这让我相信它与 domainEvents 暂时性有关。

Spring Data REST 的RepositoryEntityController如下所示:

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。当我的断点在RepositoryEntityControllerEventPublishingRepositoryProxyPostProcessor$EventPublishingMethodInterceptor捕获时,它实际上是我的对象的不同实例(不同的对象 id),唯一缺少的是 domainEvents 并且没有任何东西被触发。

更新:阅读下面我的评论,它不起作用,因为实体已分离。

4

0 回答 0