Spring Boot和MongoDB的域事件 [英] Domain Events with Spring Boot and MongoDB

查看:167
本文介绍了Spring Boot和MongoDB的域事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 MongoDB DDD Spring >。

I am working with DDD and Spring using MongoDB.

现在,由于 MongoDB DocumentDB 而没有存在模式验证, AggregateRoot 和存储在MongoDB中的Document类是两个不同的类,而 Repository 在读取和写入数据到数据库的同时,在这两个类之间转换内容。

Now the since MongoDB is a DocumentDB and no schema validations are present, The AggregateRoot and the Document class that gets stored in the MongoDB are two different classes and the Repository translates content between those two classes while reading and writing data to database.

由于Root实体类与存储在数据库中的类不同,因此Spring不会触发 DomainEvents AggregateRoot 的值。

Since the Root entity class is different from the class being stored to DB, Spring doesn't trigger the DomainEvents of the AggregateRoot.


  • 在将数据存储到数据库之后,是否有办法从存储库中触发Root实体的事件? (也许通过显式调用)

  • Is there a way I can get trigger the events of the Root entity from the Repository after storing the data to the database? (maybe by an explicit invoke)

因为MongoDB和Aggregates是1:1匹配的。因此,这是否意味着我们通常不应该创建两个不同的类,一个作为 AggregateRoot ,另一个作为在MongoDB中存储聚合根的文档类?

Since the MongoDB and Aggregates are a 1:1 fit. So does that mean that we generally shouldn't make a two different classes one as AggregateRoot and another the Document Class for storing aggregate roots in mongoDB? Wouldn't we have to add @Document annotation on top of our Aggregate which would leak infrastructure code in our Domain Model?

推荐答案

过了一会儿,我就找到了解决方案,我认为其他人也面临着同样的问题,下面是解决方案:

After a while I figured out the solution, from the upvotes I believe others are facing the same problem, here is the solution:

答案:是的,可以。在 SpringBoot 中,我们可以使用/ Autowire ApplicationEventPublisher 接口和然后调用 publishEvent(event)方法。

Answer: Yes, we can. In SpringBoot we can use/Autowire the ApplicationEventPublisher interface and then call publishEvent(event) method.

如果要为Db收集和聚合创建单独的类,则需要公开从 AbstractAggregateRoot< T> <开始,在总计中清除 DomainEvents ClearingDomainEvents 的方法/ code>具有受保护的这些方法。以下是在创建时引发事件的示例:

If you're making a separate class for Db collection and Aggregate you would need to expose out your DomainEvents and a method for ClearingDomainEvents in your aggregate since the AbstractAggregateRoot<T> has these methods as protected. Below is an example of raising an event on creation:

public class MyAggregateRootClass extends AbstractAggregateRoot<MyAggregateRootClass> 
{
    public MyAggregateRootClass(String property1, String property2) {

        // set the fields here
        registerEvent(new MyAggregateRootCreated(someArgs));
    }

    public Collection<Object> getDomainEvents() {
        return super.domainEvents();
    }

    public void clearDomainEvents() {
        super.clearDomainEvents();
    }
}

存储库代码如下:

@Repository
@RequiredArgsConstructor // using lombok here, you can create a constructor if you want
public class MyAggregateRepository {

    private final ApplicationEventPublisher eventPublisher;

    private final AggregateMongoRepository repository;

    public void save(MyAggregateRootClass aggToSave) {

        AggregateDao convertedAgg = new AggregateDao(aggToSave);

        repository.save(convertedAgg);

        // raise all the domain events
        for (Object event : aggToSave.getDomainEvents())
            eventPublisher.publishEvent(event);

        // clear them since all events have been raised
        aggToSave.clearDomainEvents();
    }
}




这是否意味着我们通常是否不应该创建两个不同的类,一个作为 AggregateRoot ,而另一个用于将聚合根存储在 mongoDB 中的文档类?


答案:不,这并不意味着那样。 DDD 的目标是将基础结构 Domain 并保持 Domain 与所有基础结构代码无关。如果它们相同,那么将产生以下影响:


So does that mean that we generally shouldn't make two different classes, one as AggregateRoot and another the Document Class for storing aggregate roots in mongoDB?

Answer: No, that does not mean that. The goal of the DDD would be to separate infrastructure from the Domain and keep the Domain agnostic of all infrastructure code. If they both are the same then below is the impact:


  • 在您的文件上具有 @Document 批注如果要切换框架或交换 Mongodb <,则聚合类将使您更改。 / code>和 SQL

  • 将来,如果需要更改数据库架构,则必须

  • 因为域只应在业务需求发生变化时才更改,而不是因为而更改,所以您必须设置适配器类。

  • 基础结构依赖性,将基础结构批注爬入 AggregateRoot 并不是最好的方法

  • Having the @Document annotation on your Aggregate Class would make you change your Domain if you're switching frameworks or swapping Mongodb with SQL.
  • In the future in case your DB schema needs to change, you would have to either also change your aggregate class or you would have to setup the adapter classes.
  • Since the domain should only change if there is a change in business requirements and not because of infrastructure dependencies, creeping in the infrastructure annotations into the AggregateRoot would not be the best way

如果您只是想保持简单并为两者使用相同的类而不创建单独的类,请确保对以下内容有所了解:

If you do want to just keep it simple and use the same class for both and not create a separate class then make sure you're sure about the below:


  • 如果您绝对确定自己永远不会切换数据库或更改框架。

  • 您有一个简单的域模型,不需要将集合实体存储在一个单独的集合中,并且您不会有那些实体最终将成长为自己的聚合

  • If you're absolutely sure that you're never going to switch DBs or change frameworks.
  • You have a simple Domain Model and you don't need to store Entities of the Aggregate in a separate collection and you there is no possibility that those Entities would ever grow into their own Aggregates

这取决于。随意发表评论,我会尽力回答所有问题,并且在堆栈上非常活跃。

In the end it depends. Feel free to drop in comments and I'll try my best to answer all of them, quite active on stack.

这篇关于Spring Boot和MongoDB的域事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆