2012-10-04 59 views
0

我是新来的春季和冬眠,所以考虑到你的答案。Spring + Hibernate:如何实现Entites和DAO

我有很多一对多的关系进行了链接表还必须包含的信息。我会尝试这种根据解决:

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的新手,我对于如何实现这个规则以及在什么级别上感到失望.IMHO我会将该逻辑放在最低级别,以便在您(开发人员)忘记检查它。那有意义吗?更好的想法或建议?

回答

0

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

  1. 唯一约束颜色
  2. 在DAO更新方法检查如果颜色已经更新存在于数据库中。如果是使用它,如果没有创建一个新
  3. 2点有一个问题,如果改变颜色和更新的同一个Hibernate Session发生。然后它会将该颜色从红色更新为蓝色,因为在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); 
    } 
} 
0

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

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

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

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

我不知道,如果这是一个非常强烈的要求不能够删除未使用(没有任何引用的混合物)的颜色 - 什么是从这个增益?对于那些被引用的数据库,将会有数据库中的参照完整性约束 - 或者至少应该有。

+0

如果颜色未被使用,您可以将其删除。但假设我将“红色”和“蓝色”的混合物更改为“绿色”和“蓝色”。检查是否可以删除“红色”只是增加开销。但我想你不会检查,只是删除它,并依靠数据库限制删除?但是,那么你基本上必须添加逻辑来吞咽在限制上抛出的异常?如果我没有名字的setter,加载实体时hibernate将如何填充该字段?是不是要求? –

+0

什么是删除的用例?它是从UI驱动的,因此依靠数据库限制是一个有效的例子。如果color.mixtures.size()> 0,那么在业务层中进行检查也没有太大的害处。在二传手问题上,我认为你是对的。对不起,误导。在这种情况下,您可能希望将其限制在DAO级别上,即不要提供'updateColor'方法。也就是说,降低一级可以通过EntityManager持久/合并Color对象。 – maksimov