我们有几个聚合根,它们有两种主要的识别方式:
- 一个整数“键”,在数据库中用作主键(通过引用聚合用作外键),在应用程序内部,公共 Web API无法访问。
- 一个基于字符串的“id”,它也唯一地标识聚合根并且可以被公共 Web API 访问。
使用基于整数的私有标识符和基于字符串的公共标识符有几个原因 - 例如,数据库性能更好(8 字节整数而不是可变长度字符串)并且公共标识符难以猜测。
但是,类在内部使用基于整数的标识符相互引用,如果基于整数的标识符为 0,则表示对象尚未存储到数据库中。这会产生一个问题,因为实体在保存之前无法引用其他聚合根。
如何解决这个问题,或者我对持久性无知的理解存在缺陷?
编辑关于基于字符串的标识符
基于字符串的标识符由存储库生成,连接到 PostgreSQL 数据库,该数据库生成标识符以确保它不会与数据库中当前的任何内容发生冲突。例如:
class Customer {
public function __construct($customerKey, $customerId, $name) {
$this->customerKey = $customerKey;
$this->customerId = $customerId;
$this->name = $name;
}
}
function test(Repository $repository, UnitOfWork $unitOfWork) {
$customer = new Customer(0, $repository->generateCustomerId(), "John Doe");
// $customer->customerKey == 0
$unitOfWork->saveCustomer($customer);
// $customer->customerKey != 0
}
我假设相同的概念可用于创建具有基于整数的非 0 键的实体,并且工作单元可以使用它在数据库中不存在的事实作为插入而不是更新的原因. 上面的test()
函数将变为:
function test(Repository $repository, UnitOfWork $unitOfWork) {
$customer = new Customer($repository->generateCustomerKey(), $repository->generateCustomerId(), "John Doe");
// $customer->customerKey != 0
$unitOfWork->saveCustomer($customer);
// $customer->customerKey still != 0
}
但是,鉴于上述情况,如果工作单元未按正确顺序保存数据库对象,则可能会发生错误。解决这个问题的方法是确保工作单元以正确的顺序保存实体吗?
我希望上面的编辑能澄清我的情况。