一对多的情况,一个group中含有多个user,一个user属于一个group。
先给出两个类代码:
Group.java
@Entity
@Table(name="t_group")
public class Group {
private int id;
private String name;
private Set<User> users = new HashSet<User>();
@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")
public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
}
User.java
@Entity
@Table(name="t_user")
public class User {
private int id;
private String name;
private Group group;
@ManyToOne
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;
}
}
先测试多对多双向关联,保存一个对象数据后,另一个对象是否会同步保存进去。
@Test
public void TestSave()
{
Group g=new Group();
g.setName("g1");
User u=new User();
u.setName("u1");
u.setGroup(g);
new SchemaExport(new AnnotationConfiguration().configure()).create(false, true);
SessionFactory sf=new AnnotationConfiguration().configure().buildSessionFactory();
Session sess=sf.getCurrentSession();
sess.beginTransaction();
sess.save(u);
sess.getTransaction().commit();
sf.close();
}
这样会报错,故默认情况下并不会将g 顺便保存进数据库。
可以设置User.java 或 Group.java
@ManyToOne(cascade=CascadeType.ALL)
cascade不会影响读,会影响增删改。
fetch管读。
fetch的用法与cascade并无大的差别,FetchType.EAGER 表示读取一个数据时,与其相关联的对象也被读取。
FetchType.LAZY表示读取一个数据时,与其相关联的对象不会被读取。
笔记:
-
如果你认为你会经常在某个事务中同时用到父对象与子对象,并且你希望少打点儿字,可以考虑使用
cascade="persist,merge,save-update"
。
可以使用cascade="all"
将一个关联关系(无论是对值对象的关联,或者对一个集合的关联)标记为父/子关系的关联。 这样对父对象进行save/update/delete操作就会导致子对象也进行save/update/delete操作。
此外,一个持久的父对象对子对象的浅引用(mere reference)会导致子对象被同步save/update。 不过,这个隐喻(metaphor)的说法并不完整。除非关联是<one-to-many>
关联并且被标记为cascade="delete-orphan"
, 否则父对象失去对某个子对象的引用不会导致该子对象被自动删除。 父子关系的级联(cascading)操作准确语义如下:
-
如果父对象被
persist()
,那么所有子对象也会被persist()
-
如果父对象被
merge()
,那么所有子对象也会被merge()
-
如果父对象被
save()
,update()
或saveOrUpdate()
,那么所有子对象则会被saveOrUpdate()
-
如果某个持久的父对象引用了瞬时(transient)或者脱管(detached)的子对象,那么子对象将会被
saveOrUpdate()
-
如果父对象被删除,那么所有子对象也会被
delete()
要想删除或者更新,先做load,除了精确知道ID之外,若是精确知道,直接用QL语句。
如果想消除关联关系,先设定关系为null,再删除对应记录,如果不删除记录,该记录就会变成垃圾数据。