Jpa实体作为域模型

Jpa实体作为域模型,jpa,dns,domain-driven-design,onion-architecture,hexagonal-architecture,Jpa,Dns,Domain Driven Design,Onion Architecture,Hexagonal Architecture,根据为DDD或六边形体系结构记录的推荐实践,域模型应与与实际使用的技术(表/列名、联接等、JPA注释)联系更紧密的数据模型表示分离。这里的一个实际问题是-在这个模型中,您如何做乐观版本控制之类的事情?假设您有一个在域模型上读取-->更新-->保存的域服务。现在JPA实体可能有一个无法向上传递的版本列。因此,当save调用调用到repo时,repo实际上再次执行(model-->entity)转换和读取+更新,它将无法判断最初读取的是哪个版本的实体。 第二个问题是性能方面的考虑,其中包括一些额外的

根据为DDD或六边形体系结构记录的推荐实践,域模型应与与实际使用的技术(表/列名、联接等、JPA注释)联系更紧密的数据模型表示分离。这里的一个实际问题是-在这个模型中,您如何做乐观版本控制之类的事情?假设您有一个在域模型上读取-->更新-->保存的域服务。现在JPA实体可能有一个无法向上传递的版本列。因此,当save调用调用到repo时,repo实际上再次执行(model-->entity)转换和读取+更新,它将无法判断最初读取的是哪个版本的实体。

第二个问题是性能方面的考虑,其中包括一些额外的读取。您可以执行不同的操作:

  • 放宽域模型应与持久性模型分离的规则。没有人说DDD有应该严格遵守的“固定规则”。这意味着您将在域内使用相同的JPA实体,按照DDD规则而不是JPA规则对它们进行建模。因此,每个字段都没有get/set,所有ValueObject都没有嵌入实体,等等。但是,正如你所知道的,如果这个领域很复杂,你必须努力避免JPA陷阱
  • 在将JPA实体转换为域实体之前,将其存储在缓存中。这看起来很愚蠢,但最终持久层和域层之间的分离允许您以任何对您有用的方式实现存储库。因此,如果您的JPA实体有一个版本,我认为管理它的最简单方法就是在存储库的实现中有一种缓存。然后你可以这样继续:
  • 阅读JPA实体
  • 将其存储在缓存中
  • 发送更新的结果域实体
  • 获取更新的域实体
  • 更新缓存中的JPA实体
  • 存储它,将版本处理留给JPA
  • 忽略JPA内容,直接使用SQL。您已经拥有了域实体,编写SQL可以让您自由地根据需要完美地调整代码,而不需要JPA层的开销。您仍然可以使用缓存解决方案,在该解决方案中,您为每个Id存储您已读取的实体的版本,并以与以前相同的方式使用它
在项目中具体使用DDD没有银弹解决方案。这取决于你的需要和愿望

我应该快点完成吗? 我可以在持久化到域转换层上投入一点时间吗

这段代码是不是后来有人使用/更改过,如果我不加“锁”的话,它会做一些奇怪的事情

我是否正在尝试创建一个纯DDD实现


我是否应该放松一些规则,在我的项目中或向我的团队慢慢介绍DDD?

有不同的方法。这主要取决于应用程序/层在体系结构中的位置。大多数时候,与实体模型通信的应用程序/层处于基础级别。你没有义务在毫无意义的情况下制造分离。沟通的证明将始终是与该层对话的层,因此我认为不需要再创建一个过渡。您可以只传递实体模型/实例数据