牵扯到对一个实体对象做操作,是否要对关联的另外一个实体对象做操作。
这里来探讨一下更新update在“多对一”关联关系中的问题:
User.java:
package cn.edu.hpu.one2many; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.ManyToOne; import javax.persistence.Table; @Entity @Table(name="m_user") public class User { private int id; private String name; private Group group; //只要有双向就要指定制定一个属性(mapedby) //不指定的话会有两个相同的字段产生 @ManyToOne(cascade={CascadeType.ALL},fetch=FetchType.LAZY) public Group getGroup() { return group; } public void setGroup(Group group) { this.group = group; } @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
Group.java:
package cn.edu.hpu.one2many; import java.util.HashSet; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.Table; @Entity @Table(name="m_group") public class Group { private int id; private String name; private Set<User> users=new HashSet<User>(); //选择set的原因是因为,set互相之间不会有重复的 //跟数据库模型比较匹配 @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @OneToMany(mappedBy="group", cascade={CascadeType.ALL}, fetch=FetchType.LAZY ) public Set<User> getUsers() { return users; } public void setUsers(Set<User> users) { this.users = users; } }
修改数据的测试:
@Test public void testUpdateUser(){ sessionFactory=new AnnotationConfiguration().configure().buildSessionFactory(); Session s=sessionFactory.openSession(); s.beginTransaction(); User u=(User)s.load(User.class,2); u.setName("user22"); u.getGroup().setName("gggg"); //load取出的只是对象的代理,用user的时候才会发出sql语句去取 //很显然后面用到了,所以它发出sql语句去取了。当commit()的时候会查看 //user在缓存中是否和数据库中的数据一样,不一样的话它会去修改数据库 //中的值,此时会发出update的语句,和直接update的效果一样。 s.getTransaction().commit(); }
测试2:
@Test public void testUpdateUser(){ sessionFactory=new AnnotationConfiguration().configure().buildSessionFactory(); Session s=sessionFactory.openSession(); s.beginTransaction(); User u=(User)s.load(User.class,3); s.getTransaction().commit(); u.setName("userTom"); u.getGroup().setName("gTom"); s.beginTransaction(); s.update(u); s.getTransaction().commit(); }
打印的sql语句:
Hibernate:
select
user0_.id as id1_0_,
user0_.group_id as group3_1_0_,
user0_.name as name1_0_
from
m_user user0_
where
user0_.id=?
Hibernate:
select
group0_.id as id0_0_,
group0_.name as name0_0_
from
m_group group0_
where
group0_.id=?
Hibernate:
update
m_user
set
group_id=?,
name=?
where
id=?
Hibernate:
update
m_group
set
name=?
where
id=?
发现相关的group更新了,这是因为设置了cascade={CascadeType.ALL}的原因。
当设置cascade={CascadeType.MERGE,CascadeType.PERSIST}的时候,
Hibernate:
select
user0_.id as id1_0_,
user0_.group_id as group3_1_0_,
user0_.name as name1_0_
from
m_user user0_
where
user0_.id=?
Hibernate:
select
group0_.id as id0_0_,
group0_.name as name0_0_
from
m_group group0_
where
group0_.id=?
居然不更新关联的group,查看文档,说明只有用MERGE,PERSIST方法的时候才会去做级联的更新,其他的属性一样。
其实最简单的就是设ALL就行了。
尊重开源精神,尊重劳动成果,转载请注明出处:http://blog.csdn.net/acmman/article/details/43889457