yan*_*isf 14 java orm inheritance hibernate
在某些继承和多态关联的情况下,为什么@ForceDiscriminator或它等效@DiscriminatorOptions(force=true)?这似乎是完成工作的唯一途径.有没有理由不使用它?
小智 11
当我一次又一次地跑过来时,我认为可能有助于澄清:首先,Hibernate在使用JOINED_TABLE映射时不需要区分.但是,它在使用时确实需要它SINGLE_TABLE.更重要的是,其他JPA提供商大多数都需要它.
Hibernate在执行多态JOINED_TABLE查询时实际上做的是创建一个动态命名的鉴别器clazz,使用case-switch在外部连接继承树中涉及的所有表之后检查是否存在对于具体子类唯一的字段."hibernate.show_sql"在您的房产中包含房产时,您可以清楚地看到这一点persistence.xml.在我看来,这可能是JOINED_TABLE查询的完美解决方案,所以Hibernate人员吹嘘它是正确的.
执行更新和删除时,问题有所不同; 这里hibernate首先在你的root-table中查询与语句的where子句匹配的任何键,并pkTable从结果中创建一个虚拟.然后它"DELETE FROM / UPDATE table WHERE pk IN pkTable"为你的继承树执行任何具体的类; IN运算符导致O(log(N))扫描每个表条目的子查询,但它可能在内存中,因此从性能角度来看也不算太糟糕.
为了回答你的具体问题,Hibernate在这里看不到问题,从某个角度看它们是正确的.@DiscriminatorValue通过在期间注入鉴别器值来简单地遵守注释将是非常容易的entityManager.persist(),即使它们实际上没有使用它们.然而,不尊重鉴别器列JOINED_TABLE有利于(对于Hibernate)创建一个温和的供应商锁定案例,并且通过指向卓越的技术甚至可以防御.
@ForceDiscriminator或者@DiscriminatorOptions(force=true)肯定有助于缓解一点痛苦,但你必须在创建第一个实体之前使用它们,或者强制使用SQL语句手动添加缺少的鉴别器值.如果您敢于远离Hibernate,至少需要花费一些代码来删除这些Hibernate特定的注释,从而产生对迁移的阻力.这显然是Hibernate在这种情况下所关心的.
根据我的经验,供应商锁定是每个市场领导者最疯狂梦想的天堂,因为它是马基雅维利亚魔术棒,可以毫不费力地保护市场份额; 因此,只要客户不反击并强制给予高于收益的供应商的价格,就会这样做.谁说开源世界会有什么不同?
ps,只是为了避免任何混淆:我与任何JPA实现者无关.
pps:我通常做的是在迁移时间之前忽略问题; 然后你可以SQL UPDATE ... FROM使用相同的case-switch-with-outer-join技巧来制定声明,Hibernate使用它来填充缺少的鉴别器值.一旦你理解了基本原理,它实际上很容易.
小智 6
伙计们让我试着解释一下@DiscriminatorOptions(Force=true)。嗯,它用于单表继承,我最近在其中一种场景中使用了它。我有两个实体映射到单个表。当我试图获取一个实体的记录时,我从两个实体中获取了包含记录的结果列表,这是我的问题。为了解决这个问题,我使用 @DiscriminatorOptions(Force=true)了它将使用 Discriminator 列创建谓词,并将指定的值映射到相应的实体。所以我使用后查询将如下所示@DiscriminatorOptions(Force=true)
select *
from TABLE
where YOUR PREDICATE AND DiscriminatorColumn = DiscriminatorValue
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9202 次 |
| 最近记录: |