其实简单点说 就是MappedBy确定"维护关系"的一方,也仅仅是"维护关系"而已.其他的操作不影响.
实验环境:hibernate 3.6.10.Final
实体类:User(多方) Classroom(一方) Many-to-One的测试
- //多方:
- @ManyToOne(cascade=CascadeType.ALL)
- @JoinColumn(name="cid")
- public Classroom getClassroom() {
- return classroom;
- }
- public void setClassroom(Classroom classroom) {
- this.classroom = classroom;
- }
- //一方
- @OneToMany(mappedBy="classroom")
- public Set<User> getUsers() {
- return users;
- }
- public void setUsers(Set<User> users) {
- this.users = users;
- }
从多方插入就不再累述了.
这里就试着从不维护关系的一方来插入:
- User user=new User();
- user.setUname("aa");
- user.setUpass("bb");
- Classroom cr=new Classroom();
- cr.setClassname("class one");
- Set<User> users=new HashSet<User>();
- users.add(user);
- cr.setUsers(users);
这样只有一条insert 语句:
Hibernate: insert into Classroom (cname) values (?)
为了更好地说明问题,我把以上一方的配置进行修改
加入了 cascade=CascadeType.ALL
同样执行以上代码 显示插入了两条:
Hibernate: insert into Classroom (cname) values (?)
Hibernate: insert into User (cid, uname, upass) values (?, ?, ?)
但是查看数据库就会发现:
虽然插入了..但是外键却没有值
一方不维护关系就可以明显的看出来,
但是一方的其他不影响关系的更新操作是没有问题的:
- Classroom cr=(Classroom)session.get(Classroom.class, 1);
- System.out.println(cr.getUsers().iterator().next().getUname());
- cr.getUsers().iterator().next().setUname("XX");
执行以上的代码:
显示:
Hibernate: select classroom0_.cid as cid1_0_, classroom0_.cname as cname1_0_ from Classroom classroom0_ where classroom0_.cid=?
Hibernate: select users0_.cid as cid1_1_, users0_.uid as uid1_, users0_.uid as uid0_0_, users0_.cid as cid0_0_, users0_.uname as uname0_0_, users0_.upass as upass0_0_
from User users0_ where users0_.cid=?
aa
Hibernate: update User set cid=?, uname=?, upass=? where uid=?
数据在数据库里也被正常更新 因为已经添加了cascade=CascadeType.ALL 一方也要维护关系
这样一番实验坐下来就可以很清楚的感觉到
mappedBy只是确定了由哪一方来维护关系而已 其他的操作并不影响.
一般情况下 如果要让两方都可以维护关系 我自己是在OneToMany后写JoinColumn 然后和ManyToOne里的外键列名取一样的。
当然也可以不写JoinColumn 来生成一个第三方表记录关系 但这样做没什么必要 相同的关系会被存两次.