更新字段时防止 DB4O 中的孤立对象
我想将 Person 对象存储在 DB4O 中。人员位置字段可能会随着时间的推移而更改。因此,我从数据库中检索一个人,并调用一个方法将位置字段设置为新的位置对象。 (我希望位置对象是不可变的,即 DDD 值对象)。
这是可行的,但是先前分配的位置对象仍然保留在数据库中。如何配置 DB4O 来删除这些孤立的 Location 对象?或者我是否需要一些自定义流程来进行垃圾收集?
此示例的简化类:
class Person {
Location location;
public void Move(Location newLocation) {
location = newLocation;
}
}
class Location {
public Location(string city) {
this.City = city;
//etc
}
public readonly string City;
/// more fields...
}
编辑:更多信息 - Person 意味着 DDD 聚合根。因此,一个人的内部状态没有任何外部参考。如果 Person 更新其位置,则旧位置应该不复存在。
I want to store Person objects in DB4O. The Person Location field can be changed over time. So I retrieve a person from the DB and call a method to set the location field to a new Location object. (I want the Location objects to be immutable i.e. DDD Value Objects).
This works, however the previously assigned Location objects remain the database. How can I configure DB4O to remove these orphaned Location objects? Or do I need some custom process to garbage collect?
Simplified classes for this example:
class Person {
Location location;
public void Move(Location newLocation) {
location = newLocation;
}
}
class Location {
public Location(string city) {
this.City = city;
//etc
}
public readonly string City;
/// more fields...
}
EDIT: Some more information - Person is meant to be an DDD aggregate root. So there are no external references to a person's internal state. If Person updates its location, then the old location should cease to exist.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
对我来说,这确实像是一笔交易。
正如 German 所说,您必须删除旧的,存储并分配新的,并确保这些步骤可以一次性完成。
在 RDBMS 中,您还必须为此提出一个事务。然而,许多 RDBMS 系统通过触发器和事件来支持您。请注意,db4o 还提供某些回调。
我目前正在研究类似情况的引用计数抽象,但一般处理起来非常棘手。另一方面,您可以编写一个特定的
Update
方法来简化事务并比较新旧对象的引用。如果它们不匹配,并且您可以确定没有其他人引用该类型的地址对象,则可以将其删除。另请注意,如果您使用没有垃圾收集的语言,您还必须手动跟踪它并删除旧对象。
“聚合根”的概念对我来说似乎很模糊——毕竟,这取决于视角,但那是另一个问题。
This really looks like a transaction to me.
Like German said, you will have to delete the old, store and assign the new one and make sure these steps can be committed in one go.
In a RDBMS, you'd have to come up with a transaction for this, too. However, many RDBMS systems support you here with triggers and events. Note that db4o also offers certain callbacks.
I'm currently working on a ref-count abstraction for cases like this, but it is very tricky to handle generically. On the other hand, you could write a specific
Update
method that simplifies the transaction for you and compares old and new objects' references. If they don't match and you can be sure that nobody else references that type of address object, you can delete it.Also note that were you using a language without garbage collection, you'd also have to keep track of this manually and delete the old object.
That 'aggregate root' concept seems very vague to me - after all, it depends on the perspective, but that is another issue.
首先在旧位置使用 db4o 的
delete()
,然后存储新位置怎么样?最好的!
德语
How about using db4o's
delete()
first on the old location and then storing the new one?Best!
German
根据db4o 8.0 API参考cascadeOnDelete(boolean),旧对象应该被自动删除。这是文档的副本,请检查给定的示例。
但它并不像打印的那样工作,很奇怪。
According to db4o 8.0 API reference of cascadeOnDelete(boolean), the old object should be deleted automatically. Here is a copy of the doc, check the given example.
However it doesn't work as printed, weird.
我认为没有完美的解决方案。但通过一些工作,您几乎可以实现这种行为。类似的主题是 这里已经讨论过。
第一步是激活位置字段上的级联删除。因此,当删除一个人时,该位置也会被删除。
configuration.common().objectClass(Person.class).objectField("location").cascadeOnDelete(true);
现在我们需要处理位置变化的情况。这个想法是这样的:
Java-Demo 实现了这种行为。
好吧,这只是一个概念,距离可接受的解决方案还有很长的路要走:
I think there's no perfect solution available. But with some work you can nearly achieve this behavior. A similar topic is already discussed here.
The first step would be to activate cascade-deletion on the location-field. So when a Person is deleted the location is also deleted.
configuration.common().objectClass(Person.class).objectField("location").cascadeOnDelete(true);
Now we need to handle the changing location case. The idea is this:
There is Java-Demo which implements this behavior.
Well, this is only the concept, it's a long way to an acceptable solution:
您是否考虑过将其设为值类型?
Have you thought about making it a value type?