ORMLite - 强制读取对象具有相同的标识

发布于 2024-11-24 07:15:23 字数 600 浏览 2 评论 0原文

我正在使用 ORMLite 读取对象的层次结构。它的形状像一棵树,父级有一个由 0+ 个子级组成的 @ForeignCollection,每个子级都通过 @DatabaseField(foreign=true)< 引用其父级。 /代码>。我正在立即读取并保存整个层次结构。

由于我对 ORM 以及 ORMLite 都很陌生,所以我不知道当读取数据库中具有相同 ID 的对象时,它们不会被创建作为具有相同身份的实际相同对象,但作为具有相同 ID 的多个重复项。意思是,我现在面临的问题是(假设“->”代表“指”)A -> B-> C!=C-> B->答:

我想通过提供的 DAO 手动读取它们并通过 ID 将它们放在一起来解决问题,确保具有相同 ID 的对象具有相同的标识

有 ORMLite 原生的方法来解决这个问题吗?如果是,是什么,如果不是,解决这个问题的常用方法是什么?这是 ORM 的普遍问题吗?它有名字吗(我想了解更多信息)?

编辑:

我的层次结构是,一栋建筑物包含多个楼层,其中每个楼层都知道其建筑物,并且每个楼层包含多个区域,其中每个区域都知道其楼层。

I'm reading a hierarchy of objects with ORMLite. It is shaped like a tree, parents have a @ForeignCollection of 0+ children, and every child refers to its parent with @DatabaseField(foreign=true). I'm reading and saving the whole hierarchy at once.

As I'm new to ORM in general, and to ORMLite as well, I didn't know that when objects with the same ID in the database are read, they won't be created as the actually same object with the same Identity, but as several duplicates having the same ID. Meaning, I'm now facing the problem that (let's say "->" stands for "refers to") A -> B -> C != C -> B -> A.

I was thinking to solve the problem by manually reading them through the provided DAOs and puting them together by their ID, assuring that objects with the same ID have the same identity.

Is there are ORMLite-native way of solving this? If yes, what is it, if not, what are common ways of solving this problem? Is this a general problem of ORM? Does it have a name (I'd like to learn more about it)?

Edit:

My hierarchy is so that one building contains several floors, where each floor knows its building, and each floor contains several zones, where every zone knows its floor.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

七禾 2024-12-01 07:15:23

这是 ORM 的普遍问题吗?它有名字吗(我想了解更多信息)?

它是 ORM 的通用模式,称为“身份映射”:在会话中,无论在代码中的何处从 ORM 获取映射对象,都只会有一个对象代表数据库中的特定行(即具有这是主键)。

我喜欢这种模式:您可以在代码的一部分中从数据库中检索某些内容,甚至可以对其进行修改,将该对象存储在实例变量中等等......而在代码的另一部分中,如果您掌握了同一“数据库行”的对象(通过任何方式:您将其作为参数传递,您对数据库进行了批量查询,您创建了一个主键设置为相同的“新”映射对象并将其添加到会话),您最终将得到相同的对象。 – 即使是之前的修改(包括未刷新的)也会在那里。

(因此,向会话添加映射对象可能会失败,并且根据 ORM 和编程语言,此添加可能会给您返回另一个“相同”对象)

Is this a general problem of ORM? Does it have a name (I'd like to learn more about it)?

It is a general pattern for ORMs and is called “Identity Map”: within a session, no matter where in your code you got a mapped object from the ORM, there will be only one object representing a specific line in the db (i.e. having it’s primary key).

I love this pattern: you can retrieve something from the db in one part of your code, even do modifications to it, store that object in a instance variable, etc... And in another part of the code, if you get hold of an object for the same “db row” (by whatever means: you got it passed as a argument, you made a bulk query to the db, you created a “new” mapped object with the primary key set to the same and add it to the session), you will end up with the same object. – Even the modifications from before (including unflushed) will be there.

(adding an mapped object to the session may fail because of this, and depending on the ORM and programming language this adding may give you another object back as “the same”)

染墨丶若流云 2024-12-01 07:15:23

不幸的是,没有 ORMLite 原生的方法来解决这个问题。更复杂的 ORM 系统(例如 Hibernate)具有专门为此原因而存在的缓存层。 ORMLite 没有缓存层,因此它不知道它刚刚“最近”返回了具有相同 id 的对象。这是 Hibernate 缓存的文档:

http://docs.jboss.org/ hibernate/core/3.3/reference/en/html/performance.html

然而,ORMLite 被设计为 Lite,而缓存层违反了 IMO 的指定。关于您在 ORMLite 中的问题,我看到的唯一[不幸的]解决方案是做您正在做的事情——根据 ids 重建对象树。如果您提供有关您的层次结构的更多详细信息,我们也许能够提供更具体的帮助。


因此,在对您的案例进行了更多思考之后@riwi,我想到,如果您有一个包含楼层集合的建筑物,则没有理由不能使用以下命令设置集合中每个楼层上的建筑物对象:父建筑对象。呃。 ORMLite 拥有实现这一目标所需的所有信息。我实现了这个行为并在 4.24 版本中发布。

编辑:

ORMLite 版本 4.26 开始,我们添加了一个对象缓存的初始版本,该缓存可以支持所要求的功能。这是文档:

http://ormlite.com/docs/object-cache

Unfortunately there is not a ORMLite-native way of solving this problem. More complex ORM systems (such as Hibernate) have caching layers which are there specifically for this reason. ORMLite does not have a cache layer so it doesn't know that it just returned an object with the same id "recently". Here's documentation of Hibernate caching:

http://docs.jboss.org/hibernate/core/3.3/reference/en/html/performance.html

However, ORMLite is designed to be Lite and cache layers violate that designation IMO. About the only [unfortunate] solution that I see to your issue in ORMLite is to do what you are doing -- rebuilding the object tree based on the ids. If you give more details about your hierarchy we may be able to help more specifically.


So after thinking about your case a bit more @riwi, it occurred to me that if you have a Building that contains a collection of Floors, there is no reason why the Building object on each of the Floors in the collection cannot be set with the parent Building object. Duh. ORMLite has all of the information it needs to make this happen. I implemented this behavior and it was released in version 4.24.

Edit:

As of ORMLite version 4.26 we added an initial take on an object-cache that can support the requested features asked for. Here are the docs:

http://ormlite.com/docs/object-cache

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文