【发布时间】:2012-02-23 21:44:57
【问题描述】:
我正在尝试通过休眠使用 JPA2.0 设计一个实体模型。
我有一个这样的域:有很多餐馆,所以显然有一个餐馆实体。每家餐厅都有许多不同的菜肴供应,0 对多的餐厅可能供应相同的菜肴。每道菜都有多种食材,有些菜品会共用食材。每种成分都有几种营养成分,每种营养成分也可能被0对多的成分所拥有。
我正在苦苦挣扎,因为我什至不确定我的问题到底是什么,但我知道我错过了一些东西。我认为问题在于如何准确地执行域模型以及主键和 .equals/.hashcode 方法的含义。
最初我打算使用生成的代理键。每个实体都会有类似
@Id
@GeneratedValue
public Long id;
.equals 将测试除 id 之外的所有实体成员的相等性。例如,无论 Long id 的值如何,一家餐厅都是相等的,但它的 List 成员是否相等。 (当然 Dish 会一直调用 .equals 一直到营养的层次结构。)
所以当我给一个 DAO bean 一个餐厅时,我只希望它在数据存储中没有等效的餐厅(通过 .equals)时保持不变。但我想这将涉及一个相当费力的 jpql 调用,我觉得它既不优雅也不高效(如果我错了,请告诉我。我经常错...哈哈)。在此过程中,如果它遇到说已经在数据存储中的成分(但不是菜肴的一部分,因此是新持久的),它会将新菜肴与已经存在的成分相关联,而不是创建一个全新的(和逻辑上重复)成分。
我想得越多,在这个等级制度的更高层坚持下去听起来就越痛苦。
我开始研究组合键(通过@IdClass 或@EmbeddedId)的想法,该组合键本身将包含子成员。这似乎在层次结构中坚持更高的东西就像通过 id 查找和坚持如果我没有找到任何东西一样简单。但我对此很怀疑……这似乎不对。这意味着我正在创建实体,其中所有成员和实体本身以及复合键的一部分。
一些注意事项。营养素的数量相对有限。成分的空间是 {numOfNutrients}^{typesOfNutrients},可能相当大。当我们到达餐厅时,客户几乎不可能意外地建造一个重复的餐厅,因为空间真的很大。有一点我实际上并不关心数据存储中是否存在重复项,因为它不太可能发生。事实上,看看这是否会发生几乎会很有趣。也不是说餐厅的例子是人为的。我的真实域名在形式上是相似的。
对不起,漫无边际。我知道帖子里有很多想法。但我觉得它们都非常相关,我想一次将它们全部提出来。
有人可以提供一些魔法吗?
我知道这个帖子:A class that behaves like @Entity and @Embeddable 通常我会看到类似的情况,“除非在特殊情况下”,否则不要这样做。这就是我所说的其中一种情况。如果不是,那么使用它的合适情况到底是什么。
还要注意,一旦将餐厅放入数据库,它的表示是不可变的。我意识到这个人为的例子是不现实的,但我的领域就是这种情况。这让我觉得让所有成员成为复合键的一部分是要走的路....
【问题讨论】:
-
我不明白“相等”部分。比如说餐厅 R1 和 R2,他们都提供菜肴 (D1,D2,D3)。那么,他们是平等的,不允许吗?但您确实说过“0 对多的餐厅可能提供相同的服务。”
-
餐厅 R1 和 R2 是相等的,前提是它们都拥有完全相同的菜肴列表,这是通过检查所有菜肴的 .equals 来确定的。它在某种意义上是递归的。 R1:(D1,D1,D3)==R2:(D1,D2,D3),但是 R1(D1,D2,D3)!=R3:(D1,D6)。因此,一道菜可能由 0 家餐厅供应。
标签: hibernate jakarta-ee orm jpa-2.0