【问题标题】:Spring + Hibernate: How to implement Entites and DAOsSpring + Hibernate:如何实现实体和 DAO
【发布时间】:2012-09-25 08:40:38
【问题描述】:

我是 spring 和 hibernate 的新手,所以在你的回答中考虑到这一点。

我有一个多对多的关系,链接表也必须包含信息。我将尝试根据以下方式解决此问题:

How Do I Create Many to Many Hibernate Mapping for Additional Property from the Join Table?

我的问题与:

hibernate: Custom code on insert / update

但我只是在这里重复一遍,所以不需要点击链接:

假设我们有颜色。用户可以创建 n 种颜色的混合物并将该混合物存储在数据库中。稍后,如果用户搜索颜色“蓝色”,则应显示所有包含蓝色的混合物。

业务规则是任何颜色都只能在数据库中出现一次。因此,如果插入新的混合物,则必须首先检查所有颜色是否已在数据库中,如果是,则应重复使用(引用)该颜色,否则应创建新的。

如果更改了混合物,例如“蓝色”被“红色”替换,则行为必须是最初的“蓝色”保持不变,系统检查“红色”是否存在并重新使用它或创建它然后添加混合起来。

重要的部分是“颜色”由系统管理,现有颜色不得更改。“红色”将始终为“红色”,不得更改为“蓝色”。由于我是 Hibernate 和 Spring 的新手,我对如何实现这个规则以及在什么级别上有点迷茫。恕我直言,我会把这个逻辑放在可能的最低级别,这样如果你(开发人员)它就不会中断忘记检查它。那有意义吗?更好的想法或建议?

【问题讨论】:

    标签: spring hibernate many-to-many


    【解决方案1】:

    如果我们可以使用相同的颜色和混合示例,它们可能看起来像这样:

    public class Color {
      String name;
      List<Mixture> mixtures;
      public String getName() { return name; }
      ...    
    }
    
    public class Mixture {
      String name;
      List<Color> colors;
    }
    

    所以我认为确保您的颜色永远不会被重命名的最简单方法,就是不提供 setter setName。确保您的颜色永远不会被删除变得有点棘手。但是,如果您要为持久性提供 DAO 方法,则不要提供 deleteColor 方法。

    我不确定不能删除未使用的颜色(没有被任何混合物引用)是否是一个非常严格的要求 - 这样做有什么好处?对于那些被引用的,数据库中会有参照完整性约束——或者至少应该有。

    【讨论】:

    • 你是对的,如果一个颜色未被使用,它可以被删除。但是假设我将“红色”和“蓝色”的混合物更改为“绿色”和“蓝色”。检查是否可以删除“红色”只会增加开销。但我猜你不会检查并删除它并依赖数据库限制删除?但是你基本上必须添加逻辑来吞下限制上抛出的异常?如果我没有名称的设置器,那么在加载实体时,hibernate 将如何填充该字段?不需要setter吗?
    • 删除的用例是什么?它是从 UI 驱动的,因此它是依赖数据库限制的有效案例。如果color.mixtures.size() &gt; 0,在业务层做检查也没什么坏处。关于二传手的问题,我认为您是正确的。抱歉误导。在这种情况下,您可能希望在 DAO 级别上对此进行限制,即不提供 updateColor 方法。话虽如此,低一级总是可以通过 EntityManager 持久化/合并 Color 对象。
    【解决方案2】:

    所以这是我目前的解决方案:

    1. 颜色的唯一约束
    2. 在 DAO 更新方法中检查要更新的颜色是否已存在于数据库中。如果是,则使用它,如果不是,则创建一个新的
    3. 如果颜色更改和更新发生在同一个休眠会话中,则第 2 点会出现问题。然后它会将颜色从红色更新为蓝色,因为在 2 中完成的查询将始终返回我们正在更新的颜色!我通过将 @Immutable 添加到 Color 实体类来解决这个问题。

    2 的代码。

    public Color update(final Color color) {
        SQLQuery query = this.getCurrentSession().createSQLQuery(
            "select * from colors where color = :color")
            .addEntity(Color.class);        
        query.setString("color", color.getColor());
        Color result = (Color) query.uniqueResult();
        if (result == null) {
            Color newColor = 
                    new Color(color.getColor());
            this.getCurrentSession().persist(newColor);
            return newColor;
        } else {
            return (Color) this.getCurrentSession().merge(result);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-25
      • 1970-01-01
      • 2016-10-28
      • 2013-02-24
      • 1970-01-01
      • 1970-01-01
      • 2020-06-01
      • 2013-05-09
      相关资源
      最近更新 更多