hibernate,每个类继承的表,不同的键列名,nee多对一的集合

时间:2011-10-21 11:49:24

标签: hibernate inheritance cascading-deletes

这是我的要求:

  1. 我有一个现有的数据库方案,我无法改变。
  2. 我有一个父表和几个子表。
  3. 所有子表都具有相同格式但名称不同的键列。
  4. 具体的子表集对于不同的安装会有所不同。
  5. 为了参考完整性,我需要删除父实体时删除所有子实体。
  6. 需要通过Hibernate管理这个级联删除,我通过一些 delete()方法自行控制删除。
  7. 所以我可能的解决方案如下所示:

    1. 我从一个超类或界面继承所有子类,比如 Child
    2. 在父实体类中,我添加设置
    3. 类型的@OneToMany字段
    4. 删除父实体后,我为所有孩子调用 delete()
    5. 不起作用的解决方案:

      1. 每个具体类继承策略的表不起作用,因为子表中的键列具有不同的名称,hibernate不支持。
      2. 将@OneToMany字段添加到每个子表的父级都不起作用,因为每个安装的子表集都不同。所以它们不能在父母中明确引用。

1 个答案:

答案 0 :(得分:0)

我认为唯一的解决方案是让每个安装都提供所有子类的列表,并有一个循环遍历这些类的方法,选择所有具有即将被删除的父类的实例,并删除他们:

public void deleteAllChildren(Parent p) {
    List<Class<?>> classes = getListOfChildClassesFromSomewhere();
    for (Class<?> clazz : classes) {
        String hql = "select c from " + clazz.getName() + " where c.parent = :parent";
        Query q = session.createQuery(hql).setParameter("parent", parent);
        List<Object> children = (List<Object>) q.list();
        for (Object child : children) {
            session.delete(child);
        }
    }
}

您也可以直接使用删除HQL查询,但这会绕过会话。

如果每个sublcass使用不同的字段/属性名称引用父级,则将子类列表转换为Map<Class<?>, String>,其中String值是子类的父字段/属性名称。

如果您可以选择让所有子节点继承一个@MappedSuperClass带注释的类,其中父字段被声明并映射,您可以执行一个返回所有子节点的查询:

select child from ChildMappedSuperClass child where child.parent = :parent

但由于Java只支持单继承,因此可能不是一种选择。