代码之家  ›  专栏  ›  技术社区  ›  Andrzej Doyle

在Hibernate中建模时间型关系表

  •  2
  • Andrzej Doyle  · 技术社区  · 16 年前

    我正试图将Hibernate包装在一个现有的数据模型上,正如预期的那样,这个模型会有起伏。

    我目前的症结是,其中一个实体表有一个准时间模型;从来没有删除或更新过任何行;相反,“is_current”列被设置为“false”(并使用更新时的新字段创建新行,使用不同的主键)。

    作为冬眠的新手,我正在努力建立模型,甚至确定是否有可能。嗯,删除操作非常简单 @SQLDelete 注释,但更新看起来很棘手。理论上这看起来像 能够 做一件很简单的事情(在元代码中, @SQLUpdate(sql = @SQLDelete + "; " + @SQLInsert) )但是有明显的复杂性(这是因为这种语法不存在),部分原因是主键需要在两个语句之间无效并在第二个语句中更新,而且我确信还有其他数据一致性问题我还没有考虑过。

    有没有一种切实可行的方法来管理这一点,即模型更新为在休眠中删除+插入?

    编辑:为了澄清,我知道我可以通过显式地指定insert-sql,然后使用上面的代码片段(带有对sql常量的合法引用)进行更新,从而以一种蛮力的方式来实现这一点。但是,我不太想这样做,因为我很满意SQL Hibernate在默认情况下为插入生成的结果,并且如果类发生任何变化,手工写出这个结果将是非常脆弱的。这是最后一个强制通过的解决方案,但是如果我必须手工编写SQL的话,它似乎会破坏ORM映射器的作用…

    双重编辑:即使上面的方法也可能不起作用,因为我需要在SQL中指定两次主键绑定参数(不可能有问号)。 我不能说服Hibernate去从SequenceGenerator给我分配一个新的。所以看起来我需要一个程序化的方法,而不是配置的方法——除非我遗漏了一些特别相关的配置元素。

    3 回复  |  直到 16 年前
        1
  •  1
  •   RMorrisey    16 年前

    您说没有更新任何行,但听起来您正在更新该行的is_current列。我只需要使用hibernate(更新行的iscurrent字段,然后创建一个新行)做同样的事情,而不是尝试编写一个实际上是更新的自定义删除函数。

    row1.setCurrent(false);
    session.saveOrUpdate(row1);
    row2 = new Row(row1); //Copy constructor; use a different primary key (or your default primary key for a new object)
    row2.setCurrent(true);
    row2.setFoo("bar"); //whatever data updates you are doing for the new row
    session.saveOrUpdate(row2);
    

    您可以将此过程包装在一些中间层/业务逻辑代码中,以确保不会更新其他字段。

        2
  •  1
  •   non sequitor    16 年前

    我们有一个与Hibernate一起使用的完全时间星模式。然而,Hibernate从不知道审计或事实表,只知道表的视图。这允许我们像往常一样使用Hibernate,所以当Hibernate对DB中的视图发出插入、删除或更新时,将为这些相应的任务触发“而不是”触发器。

    因此,在您的例子中,创建一个视图(Hibernate不知道任何更好的情况,并且是完全透明的)和适当的触发器来设置标志和其他内容。事实上,我很惊讶我们是如何以相对较少的痛苦摆脱这种困境的——我们的设计真的可以更好,因为使用Hibernate是一个事后诸葛亮/附加组件。

        3
  •  0
  •   Andrzej Doyle    16 年前

    经过进一步的研究,我相信没有一种简单的方法可以做到这一点。我想尝试的一种方法是将原始表隐藏在可更新的视图后面,这样Hibernate可以呈现出一些看起来正常的东西,而视图上的触发器将简单的CRUD操作映射到底层表中所需的操作序列。

    但是,我怀疑这可能不会太好地工作,因为我相信Hibernate在任何时间点都会维护自己对数据库内容的概念;例如,如果我删除一个实体,Hibernate的缓存会认为物理行不再存在于表中(虽然它确实存在,但现在为假)。如果这种不匹配可能导致最坏情况下的数据一致性问题,或者可能导致无效的批优化,我不会感到惊讶。

    不管怎样,现有的表都是可怕的,所以在这种变化的背景下使它们更加健全是我将采用的方法。至少这个评估阶段已经使现有模型的一些缺陷更加清晰。