1

このブログとこの参考資料を読み、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. 

更新: 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.
     }
  }
}

抽象エンティティ:

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の間のどこかにドロップされているようです。

実際に起こっていることは、エンティティの別のインスタンスが実際に傍受されており、その時点で 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