Java 避免在聚合子级的模型上使用persistence层 问题
假设以下DDD模型Java 避免在聚合子级的模型上使用persistence层 问题,java,domain-driven-design,persistence,crud,Java,Domain Driven Design,Persistence,Crud,假设以下DDD模型 class Building { Room[] rooms addRoom(String name) { room = new Room(name) // Model db.create(room) // Persistence!!! rooms.add(room) // Model } } class Room { String name } 我们可以看到,Bui
class Building {
Room[] rooms
addRoom(String name) {
room = new Room(name) // Model
db.create(room) // Persistence!!!
rooms.add(room) // Model
}
}
class Room {
String name
}
我们可以看到,Building
是AR并负责创建其聚合房间
。我的问题是,当我尝试按照CRUD模型在数据库中创建房间时。在某个时刻,可以创建一个房间,因此我的模型将调用Building
,它将创建房间
。但是,我的模型不应该使用持久层
注意您可以添加房间,这意味着您可以在数据库中创建与实际模型不一致的建筑。因此,我也必须更新我的建筑
如果我将数据库的创建移动到模型外部的房间
,那么,当我在数据库中更新我的建筑
时,房间
必须已经存在于数据库中。但是Room
是Building
的聚合子级,除了Building
之外,其他类不应该访问它
问题:
如何在模型外部的数据库中创建房间
,将房间
保留为聚合子项
如果您使用DDD,请查看存储库模式-持久性和db交互如何工作应该变得显而易见
简言之,存储库负责检索和存储整个聚合
在您的情况下,您将拥有一些与数据库交互并存储建筑的crudepository
,级联所有房间
这里需要注意的一点是:仅仅两种对象类型之间的组合可能不足以要求将建模作为一个集合。如果不变量不存在,并且不需要事务一致性,那么它们也可能是两个不同的聚合,相互引用(通过ID)如果使用DDD,请查看存储库模式-持久性和db交互的工作方式应该是显而易见的
简言之,存储库负责检索和存储整个聚合
在您的情况下,您将拥有一些与数据库交互并存储建筑的crudepository
,级联所有房间
这里需要注意的一点是:仅仅两种对象类型之间的组合可能不足以要求将建模作为一个集合。如果不变量不存在且不需要事务一致性,那么它们也可能是两个不同的聚合,相互引用(通过ID)在您的场景中,如果我没有弄错的话,Building
是保存房间
实体集合的聚合根(请记住,聚合本身也是一个实体)
类似于以下内容的存储库应该负责聚合根的持久性操作(例如,创建、查找、更新等),即构建
公共接口存储{
Building findById(字符串buildingId);
仓库(建筑物);
}
您已经正确指出,域操作(例如,在您的情况下添加房间)必须通过聚合根进行。但是,聚合根(或任何其他实体)不得承担持久性责任(正如您声称的:db.create(房间)
)
客户端通过域服务或应用程序服务与域进行交互。这些服务反过来通过其存储库检索聚合根,进行必要的修改,并将整个聚合存储在单个事务中。因此,在每次成功的事务中,您始终具有与其子事务一致的聚合n数据库,无需担心丢失父、子等
公共类SomeDomainOrApplicationService{
私有存储库;
public void createRoomServiceMethod(字符串buildingId){
//检索聚合根
Building Building=repository.findById(buildingId);
//改性骨料
字符串roomName;//指定房间名称
建筑。添加房间(房间名称);
//存储聚合
仓库、仓库(建筑);
}
}
在您的场景中,如果我没有弄错的话,Building
是包含房间
实体集合的聚合根(请记住,聚合本身也是一个实体)
类似于以下内容的存储库应该负责聚合根的持久性操作(例如,创建、查找、更新等),即构建
公共接口存储{
Building findById(字符串buildingId);
仓库(建筑物);
}
您已经正确指出,域操作(例如,在您的情况下添加房间)必须通过聚合根进行。但是,聚合根(或任何其他实体)不得承担持久性责任(正如您声称的:db.create(房间)
)
客户端通过域服务或应用程序服务与域进行交互。这些服务反过来通过其存储库检索聚合根,进行必要的修改,并将整个聚合存储在单个事务中。因此,在每次成功的事务中,您始终具有与其子事务一致的聚合n数据库,无需担心丢失父、子等
公共类SomeDomainOrApplicationService{
私有存储库;
public void createRoomServiceMethod(字符串buildingId){
//检索聚合根
Building Building=repository.findById(buildingId);
//改性骨料
字符串roomName;//指定房间名称
建筑。添加房间(房间名称);
//存储聚合
仓库、仓库(建筑);
}
}
哪种编程语言?哪种