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

发布于 2024-12-11 10:57:39 字数 638 浏览 0 评论 0 原文

这是我的要求:

  1. 我有一个无法更改的现有数据库方案。
  2. 我有一张父表和几张子表。
  3. 所有子表都具有相同格式但名称不同的键列。
  4. 对于不同的安装,具体的子表集有所不同。
  5. 为了参考完整性,我需要在删除父实体时删除所有子实体。
  6. 不需要需要由 Hibernate 管理此级联删除,我通过某种 delete() 方法自己控制删除。

因此,我可能的解决方案应如下所示:

  1. 我从一个超类或接口继承所有子类,例如 Child
  2. 在父实体类中,我添加 Set 类型的 @OneToMany 字段
  3. 当父实体被删除时,我为所有子实体调用 delete()

不起作用的解决方案:

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

here are my requirements:

  1. I have an existing db scheme which I cannot change.
  2. I have one parent table and several child tables.
  3. All child tables have key columns of same format but different names.
  4. The concrete set of child tables differs for different installations.
  5. For reference integrity sake I need all child entities removed when the parent entity is removed.
  6. I don't need this cascade removal being managed by Hibernate, I control the removal myself by means of some delete() method.

So my possible solution shall look like the following:

  1. I inherit all children classes from one superclass or interface, say Child
  2. In the parent entity class I add @OneToMany field of type Set
  3. When the parent entity is removed I call delete() for all children.

Solutions that would not work:

  1. The Table per concrete class inheritance strategy would not work, since key columns in child tables have different names, this is not supported by hibernate.
  2. Adding a @OneToMany field to parent for each child table would not work since the set of child tables differs for each installation. So they must not be explicitly references in the parent.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

北恋 2024-12-18 10:57:39

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

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 查询,但这会绕过会话。

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

如果您可以选择让所有子级继承一个 @MappedSuperClass 注解的类,其中声明并映射了父字段,则可以执行一个查询来返回所有子级:

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

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

I think the only solution is to have each installation provide a list of all the child classes, and have a method that loops through these classes, select all the instances who have the soon-to-be-deleted parent, and remove them :

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);
        }
    }
}

You could also use a delete HQL query directly, but this will bypass the session.

If each sublcass references the parent using a different field/property name, then transform the list of child classes into a Map<Class<?>, String>, where the String value is the parent field/property name for the child class.

If you have the option to make all the children inherit a single @MappedSuperClass annotated class, where the parent field is declared and mapped, you could do a single query that would return all the children :

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

But since Java only supports single inheritance, it might not be an option.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文