我有一个实体。有时我需要这个对象也包含一些值,称之为'深度'。查询可能看起来像'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中(聚合,而不是继承)。但似乎这也很不方便。 你怎么看?什么是合适的解决方案?
答案 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;
它运作良好,似乎将来可以轻松支持