Spring Data REST / Spring Data Commons Domain Events

时间:2017-08-07 03:57:52

标签: spring-boot spring-data spring-data-rest spring-data-commons

我读了这个blog和这个reference material,并确定Spring Data Commons Domain Events在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. 

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

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

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

我已经对此进行了广泛的调试,看起来DomainEvents在RepositoryEntityControllerEventPublishingRepositoryProxyPostProcessor$EventPublishingMethodInterceptor之间被删除了。

真正发生的是我的实体的不同实例实际上被截获,此时DomainEvents已不再存在。我可以确认@AfterDomainEventPublication clearDomainEvents()此时没有被调用,这让我相信它与domainEvents是瞬态的有关。

Spring Data REST&#39; s 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并且没有被触发。

更新:请阅读下面的评论,因为该实体已分离,因此无效。

0 个答案:

没有答案