【问题标题】:Null key in Identity Map身份映射中的空键
【发布时间】:2009-05-01 22:04:42
【问题描述】:

我有一个在身份映射中使用的域对象(键是对象的 Id 属性)。

伪代码:

map = new Mapping();
map[domainObj.Id] = 'foo';

我观察对象告诉我它何时被保存到数据库中:

domainObj.bind('saved', function() {
    map[domainObj.Id] = 'new foo!'
})

对于新对象,Id 字段为空并且在保存到数据库之前不会填充。

这就是我的问题。在新对象的情况下,查找“map[domainObj.Id]”失败,因为对象的身份在保存后发生了变化!

在这样的身份映射中使用对象的最佳方式是什么?

约束

  1. 我使用的语言不允许对象作为映射中的键 [JavaScript]
  2. Id 字段必须在保存新对象时在服务器上生成

更新

感谢您的反馈。我真的很想让值对象以与实体相同的方式映射:仅仅因为值对象尚未保存并不意味着它没有要映射到我的应用程序的值。我实际上误解了身份映射是什么(在重新阅读模式定义后,我发现我并没有真正使用它)。

我想出的解决方案几乎直接来自 Igor 的回答:每个对象在实例化时都会获得一个随机分配给它的 id。它在对象所在的上下文的生命周期内是唯一的、不可变的和不变的。它适用于数据库中的实体和新的实例化。实体的调整是它被设置为匹配对象的真实身份。这使得调试更容易一些。这是我在映射中用作键的值。

【问题讨论】:

  • 为什么要将瞬态对象添加到身份映射中?
  • @Paco:这不是身份映射。我误解了身份映射的用例。对于那些认为他们正在使用身份映射并遇到此问题的其他人,我保留了问题的措辞。查看我对stackoverflow.com/questions/804041/null-key-in-identity-map/…的评论

标签: design-patterns data-modeling orm


【解决方案1】:

好吧,你必须想办法推迟将对象添加到地图中,直到它被保存并分配一个 ID 之后。

【讨论】:

  • 就真正的“身份图”模式而言,您是绝对正确的。未从域中检索到的值不属于映射。事实证明,我根本没有使用真正的身份映射,而是出于查找性能原因(与扫描集合相比)碰巧依赖对象的“Id”字段的映射。
【解决方案2】:

在一个对象获得身份之前,它只是一个值对象。只有在身份建立之后,它才会成为一个实体

在对象变成实体之前,您不能真正将其放入像您这样的身份映射中 - 这没有意义,因为您无法将其拉出(因为您没有唯一的密钥来找到它)。

一种可能的方法:

  1. 在类中添加一个标志来指示对象的状态(新/已保存)。
  2. 为这些对象实现一个临时(客户端)ID
  3. 可选:
    1. 单独身份映射中保留“新”对象(如果您无法避免客户端 ID 和服务器 ID 之间的 ID 冲突)
    2. 相同身份映射中保留“新”对象(如果您可以避免客户端和服务器 ID 之间的 ID 冲突)
  4. 保存对象后,将客户端 ID 替换为服务器 ID,将状态设置为已保存,移动到主身份映射(如有必要)。

在这里查看entities vs. value objects

【讨论】:

  • 那个链接是怎么回事?我在FF,当我点击它时,我得到一个404。然后我点击进入地址栏(仍然在404页面上)并按[Enter],它就可以工作了。
  • 谢谢。请参阅我更新的问题,了解我决定做什么。唯一的变化是您答案的最后一部分:保存对象后,我不想用服务器 ID 替换客户端 ID,因为地图在保存之外并且不知道更新后的 ID(这不是“模式”意义上的真实身份图;我误用了这个词。
  • 没有 Id 的实体仍然是实体。在实体中保留持久状态标志不是一个好主意,因为它不适用于持久性无知的想法。
  • @Paco:你说的可能是真的,但在你提供更好的替代解决方案之前,我认为我的建议仍然有效。至于没有 ID 的实体仍然是实体:在哲学术语中这是真的,但在实际编程术语中它不是。一个不告诉你他的名字的人仍然是一个人,但你不会允许他在没有以某种方式表明自己身份的情况下在投票申请中注册为选民。所以在他的身份确定之前,他不是投票实体:)
  • 值对象是不可变的。不是每个没有 id 的对象都是值对象。埃里克·埃文斯 (Eric Evans) 的书中对这个主题做了很好的解释。
猜你喜欢
  • 1970-01-01
  • 2019-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-24
  • 2015-10-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多