在Clazz的OneToMany和Course的ManyToMany中,我们都可以看到有CascadeType.PERSIST和CascadeType.REMOVE。具体到底是什么意思呢?persist是指当持久化实体的时候,如果有关联的集合,并且设成persist时,连集合也一并存入数据库当中。但是如果真正写一下,然后使用的话,我们会发现:OneToMany设置这个根本不起作用。比如我新建一个班级,并直接赋予60个学生的一个集合,然后调用dao的save方法,看看数据库,怎么回事,怎么只有班级持久化了,关联学生一个没存到数据库?然后试试新建课程,并且选上要修这门课的学生,然后持久化课程,看看数据库,怎么搞的,这次双方都持久化了,即中间表已经插入了相关的记录。造成OneToMany用persist是什么原因?个人理解:学生属于一个实体,其持久化应当依靠自己相应的dao,一个一个student的存储。就好比student和course的中间表,我们上面假设中间表只有STUDENT_ID和COURSE_ID,并且分别连向student表和course表的主键,如果你有特殊需求,比如是要一个score列(课程成绩),那么这时候你还想用ManyToMany配置的话,会出现好多问题,除非你允许成绩是空的,但是即使成绩可以为空,如果你需要修改成绩怎么办呢?先取出这个学生,然后遍历其课程集合,找到这个课程然后再持久化不行?应该可以吧,但是是不是指需要先删除这个学生选的课程,然后再将这些再次持久化一次?这个方法绝对可以,不过我没人会这样。。。呵呵。。。当中间表有其他与两方表都没有关系的列时,你应当为中间表也映射一个实体,用这个实体的相应dao修改相应的记录。在这种情况下用ManyToMany还有另一个问题,如果你的hibernate session还没有关闭,你会发现提错,说你打算删除即将再次持久化的记录。使用OpenSessionInViewFilter的时候你就会发现这个问题了。呵呵。。。 还有一个,Hibernate官方不推荐使用联合主键,原来的我就不相信用联合主键会怎样,还不行吗?要不行那还不是你框架太烂?实践过之后,我改变了我的看法。。。假如你是普通的一个表,使用联合主键没有任何问题,但是假如你的表是一个中间表,并且有和两个关联表无关的列,就像T_STUDENT_COURSE,我们在设计数据库的时候,很容易想到用STUDENT_ID和COURSE_ID来作为主键,不错,但是如果你用hibernate映射实体的时候你知道有什么麻烦吗?首先这两个都是外键,在hibernate中就是需要有两个关联实体的对象引用,那么这两个作为@Id是吧?可以啊!但是当你持久化的时候,会提示student在T_STUDENT_COURSE中无法找到。为什么?因为你数据库就一个ID呀,而你这里配的可是一个实体引用呀!其实这也是可以解决了,就是解决办法迂回一点点,在hibernate外键关联的时候可以指定实体引用,就是说比如你StudentCourse实体,有一个student的引用,可以定义这样一个column:studentId,这个Id可以关联student引用,具体写法我就不写出来了,在hibernate官方文档写得相当详细,很容易验证。看,就一个外键都这样了,多个外键还得了?当然,如果普通的单外键引用不会产生这样的问题,直接配一个实体引用就可以解决问题。问题是可以解决的,关键是以后维护起来是否方便?我做过就知道,一点不简单,所以后来还是改了。。。不推荐大家使用联合主键。
posted on 2008-11-10 20:39 xskow! 阅读(828) 评论(1) 编辑 收藏 所属分类: SSH探索