【问题标题】:Hibernate: Mapping One-way Redundant ColumnsHibernate:映射单向冗余列
【发布时间】:2009-04-01 23:33:09
【问题描述】:

在我的架构中,有一些冗余列用于加速报告查询。例如,销售的采购总额保存在"sale" 表的"purchase_total" 列中,但在模型中,它是通过将销售中每件购买的售价相加来动态计算的。可以通过在 Sale 对象上调用“getPurchaseTotal”访问器来检索此值。

有没有办法在插入/更新时将此值映射到销售表中的 purchase_total 列,但在从数据库加载时不包含在销售对象的水合中?我猜它类似于派生或计算的列,但相反。

最好通过数据库本身的触发器来处理这个问题吗?

【问题讨论】:

    标签: hibernate mapping denormalized


    【解决方案1】:

    您是否尝试在模型中执行以下操作?

    public class Sales {
    
      /**
       * this set method ignores the value loaded from the database.
       */
      public void setPurchaseTotal(double val) {
        // ignore a value set explicitly by hibernate
      }
    
      /**
       * Compute the purchase total
       */
      public double getPurchaseTotal() {
         // sum item totals
         double sum = 10.0;
    
         return sum;
      }
    
    }
    

    这将忽略已加载的数据,但会在保存到数据库时保留该值。

    HTH

    【讨论】:

    • 我确实想到了这一点,但宁愿不诉诸我认为的黑客行为。当然,为了报告目的而存在这种冗余列是相当普遍的吗?
    【解决方案2】:

    我可能会在数据库中执行此操作,因为这些列与您的主应用程序无关。

    您可以使用触发器,也可以完全摆脱冗余列,并使用物化视图(Oracle 和 PostgreSQL)/索引视图(SQL Server)/自动汇总表(DB2)来查询您的报告数据。

    【讨论】:

      【解决方案3】:

      Hibernate 允许您创建类型并覆盖类型的获取/保存方法。

      创建一个类型,例如InsertableOnly,它在获取集上会丢弃数据库值。

      假设您的价值是整数,因为您以美分表示价格以避免四舍五入问题:

      class InsertOnlyInteger extends org.hibernate.type.IntegerType {
        public Object get(ResultSet rs, String name) throws SQLException {
           return null;
        }
      }
      

      然后使属性InsertOnlyInteger的Hibernate类型(带有xml或注释,因为它适合你)。

      这与sewardrobert给出的答案非常相似,但它

      1. 允许你在类中有一个“普通”的设置器,
      2. 除 Hibernate 之外的 /other/ 协作者(如您的 Java 代码求和例程)可以正常使用,
      3. 它是可重复使用的,并且
      4. 有一个像样的名称(如 InsertableOnly),它或多或少是自我记录的。

      【讨论】:

      • 这稍微好一点,但它仍然需要一个销售类的设置器,不是吗?我不需要一个 setter(出于显而易见的原因),所以为了 ORM 添加一个仍然被认为是一种 hack。
      猜你喜欢
      • 2015-09-02
      • 2021-10-16
      • 2015-11-05
      • 1970-01-01
      • 1970-01-01
      • 2011-04-24
      • 1970-01-01
      • 1970-01-01
      • 2022-01-03
      相关资源
      最近更新 更多