如何将DB中计算的属性添加到@Entity类?

时间:2011-02-11 16:25:13

标签: java oop hibernate hql hibernate-mapping

我有一个实体。有时我需要这个对象也包含一些值,称之为'深度'。查询可能看起来像'select b.id, b.name, b..., count(c.id) as depth from Entity b, CEntity c where ...'。所以我创建了一个扩展实体的类NonHibernateEntity。然后,上面写的查询结果完美地存储为NonHibEntity列表,它包含实体的所有字段(因为它们被扩展)和属性“深度”。我通过设置aliasToBean结果变换器来实现它:.setResultTransformer(Transformers.aliasToBean(NHEntity.class)). 但是,指定所有必需字段的所有别名是烦人且不方便的。 然后,如果我想将这个对象中的一个保存到DB - session.saveOrUpdate((Enity)nHibEntity) - 有一个关于nHibEntity不是Hibernate Entity的例外。

我听说过将'entity'作为字段存储在NonHibEntity中(聚合,而不是继承)。但似乎这也很不方便。 你怎么看?什么是合适的解决方案?

2 个答案:

答案 0 :(得分:1)

Formula列映射可能适合您的需求。我先试试这个。

如果您担心这会导致性能问题,您可以尝试仅在子项中使用此字段的映射类层次结构,并将两者映射到同一个表。不确定这实际上会起作用......

作为最后的手段,使用非映射类执行您现在所拥有的操作,但将实体作为另一个类中的字段 - 聚合而不是您所说的继承,并确保有一种检索方法来自未映射的实体的映射实体,以便您可以保存。将它设为Decorator是明智的,因此它既是子类又是聚合,你可以继续忽略大部分代码中的区别。

但是,使用非映射的子类和/或聚合,您必须提取实体才能保存。

答案 1 :(得分:0)

如果有人想知道 - 我以这种方式解决了这个问题:

将此计算字段设为@Transient,然后

List<BaseEntry> result = new ArrayList<BaseEntry>();
    Iterator it =  session()
    .createQuery("select b, (select count(p.id) as depth from BaseEntry p " +
            "   where ... ) as d" +
            " from BaseEntry b " +
            " where ... ")
    .list().iterator();
    while ( it.hasNext() ) {
        Object[] row = (Object[]) it.next();
        BaseEntry entry = (BaseEntry) row[0];
        Long d = (Long) row[1];
        entry.setD(d);
        result.add(entry);
    }
    return result;

它运作良好,似乎将来可以轻松支持