[英]Spring Data domain events go missing (?)
我在Spring Boot应用程序中从聚合根发布事件时遇到麻烦。 我基本上想要的是每次有关某个人的某些信息更改时都发布“更新”事件。 此代码非常简单:
@Entity
public class Person {
@Transient
private final Collection<AbstractPersonRelatedEvent> events = new ArrayList<>();
Person(Person other) {
// copy other fields
other.events.foreach(events::add);
}
// other stuff
public Person updateInformation(...) {
Person updated = new Person(this);
// setting new data on the updated person
if (!hasUpdateEventRegistered()) {
updated.registerEvent(PersonDataUpdatedEvent.forPerson(updated));
}
return updated;
}
void registerEvent(AbstractPersonRelatedEvent event) {
events.add(event);
}
@DomainEvents
Collection<AbstractPersonRelatedEvent> getModificationEvents() {
return Collections.unmodifiableCollection(events);
}
@AfterDomainEventPublication
void clearEvents() {
events.clear();
}
}
我正在通过经理来管理Person
实例:
@Service
@Transactional
class PersistentPersonManager implements PersonManager {
// other methods are omitted
@Override
public Person save(Person person) {
return personRepository.save(person);
}
}
但是,当我调用管理器( manager.save(person.updateInformation(...))
,事件似乎“丢失”了:调用save()
方法时,所有事件仍然存在,但是当Spring调用getModificationEvents()
,集合事件为空(仅执行Spring代码)。
因为这是非常基本的,所以我必须错过一些必不可少的东西,但会陷入困境。
那么如何在这里重回正轨?
我假设您在这里使用JPA。
对于JPA, save
操作实际上是在JPA EnityManager
上进行merge
。
对于分离的实体, merge
将从数据库或当前会话中加载/查找具有相同ID的实体,然后复制所有(更改的)字段。 这确实会忽略瞬态字段,例如事件。
您正在处理分离的实体,因为每次调用updateInformation
时都在创建一个新实体。
所以这是正在发生的事情:
您从数据库中加载实体( e1 )。 它没有注册任何事件。
通过调用updateInformation
您可以创建一个新的分离实体( e2 )。 您还可以向e2注册事件。
调用save
JPA将找到匹配的e1并将所有更改从e2复制到其中,事件除外。 因此, e1仍未注册任何事件。
事件被触发,但是没有任何事件,因为仅使用了e1 。
为了解决此问题:不要在updateInformation
创建实体的新实例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.