Spring + Hibernate:如何实现实体和DAO

时间:2012-10-04 10:17:20

标签: spring hibernate many-to-many

我是春天和冬眠的新手,所以在你的回答中考虑到这一点。

我有多对多的关系,链接表也必须包含信息。我会尝试按照以下方式解决这个问题:

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的新手,所以我对如何实现这个规则以及在什么级别上都有所遗漏。我会把这个逻辑放在最低级别,这样如果你(开发人员)它不会破坏忘记检查它。那有意义吗?更好的想法或建议?

2 个答案:

答案 0 :(得分:0)

如果我们可以使用相同的颜色和混合示例,它们可能如下所示:

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

public class Mixture {
  String name;
  List<Color> colors;
}

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

我不确定是否强烈要求不能删除未使用的颜色(未被任何混合物引用) - 从中​​获得了什么?对于被引用的那些,数据库中将存在参照完整性约束 - 或者至少应该存在。

答案 1 :(得分:0)

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

  1. 颜色中的唯一约束
  2. 在DAO更新方法中,检查数据库中是否已存在要更新的颜色。如果是,请使用它,如果没有创建新的
  3. 如果在同一个休眠会话中对颜色和更新进行更改,则第2点会出现问题。然后它会将该颜色从红色更新为蓝色,因为在2中完成的查询将始终返回我们正在更新的颜色!我通过将@Immutable添加到Color实体类来解决这个问题。
  4. 代码为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);
        }
    }