------------------------Hibernate多对一ManytoOne
要点:
ManytoOne配置在多端
可以配置级联操作 @ManyToOne(cascade=CascadeType.ALL)
实体:
@Entity
public class Person {//一端
@Id
@GeneratedValue
private long id;
@Column(name="name")
private String name;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@Entity
public class Phone {//多端
@Id
@GeneratedValue
private Long id;
@Column(name="number")
private String number;
@ManyToOne
private Person p;
public Person getP() {
return p;
}
public void setP(Person p) {
this.p = p;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
}
实例1:只在多端配置映射,只保存一端
Person p = new Person();
p.setName("zhangsan");
Phone ph1 = new Phone();
Phone ph2 = new Phone();
ph1.setNumber("13109361111");
ph2.setNumber("13109362222");
ph1.setP(p);
ph2.setP(p);
session.save(p);
结果:
Hibernate:
insert
into
Person
(name, id)
values
(?, ?)
只保存了Person为张三的对象。因为Person端无映射,且为瞬时态对象,直接持久化Person。
实例2.只在多端配置映射,只保存多端
Person p = new Person();
p.setName("zhangsan");
Phone ph1 = new Phone();
Phone ph2 = new Phone();
ph1.setNumber("13109361111");
ph2.setNumber("13109362222");
ph1.setP(p);
ph2.setP(p);
session.save(ph1);
session.save(ph2);
结果:[org.hibernate.TransientObjectException: object references an unsaved transient instance
Hibernate抛出异常:Phone对象引用了未持久化瞬时态的Person对象。
因为没有做级联。
实例3.只在多端配置映射,先保存一端,再保存多端
Person p = new Person();
p.setName("zhangsan");
Phone ph1 = new Phone();
Phone ph2 = new Phone();
ph1.setNumber("13109361111");
ph2.setNumber("13109362222");
ph1.setP(p);
ph2.setP(p);
session.save(p);
session.save(ph1);
session.save(ph2);
结果:
Hibernate:
insert
into
Person
(name, id)
values
(?, ?)
Hibernate:
insert
into
Phone
(number, p_id, id)
values
(?, ?, ?)
Hibernate:
insert
into
Phone
(number, p_id, id)
values
(?, ?, ?)
先持久化person,再持久化Phone,外键关联正确,执行结果完美。
实例4.只在多端配置映射,先保存多端,再保存一端
Person p = new Person();
p.setName("zhangsan");
Phone ph1 = new Phone();
Phone ph2 = new Phone();
ph1.setNumber("13109361111");
ph2.setNumber("13109362222");
ph1.setP(p);
ph2.setP(p);
session.save(ph1);
session.save(ph2);
session.save(p);
结果:
Hibernate:
insert
into
Phone
(number, p_id, id)
values
(?, ?, ?)
Hibernate:
insert
into
Phone
(number, p_id, id)
values
(?, ?, ?)
Hibernate:
insert
into
Person
(name, id)
values
(?, ?)
Hibernate:
update
Phone
set
number=?,
p_id=?
where
id=?
Hibernate:
update
Phone
set
number=?,
p_id=?
where
id=?
先保存ph1,ph2,然后保存了person,最后将外键更新至ph1,ph2。执行了5条sql,有点浪费资源。
因为保存ph1,ph2时person还未保存,所以ph1和ph2的外键为null。最后保存了person后再更新外键。
当设置关联为@ManyToOne(optional=false)外键不许为空时,则抛出异常,因为保存ph1,ph2时外键为null。
---------------在多端设置级联
要点:设置级联后,可以只保存多端,而不保存一端。持久化操作进行了传递即级联
@Entity
public class Phone {
@Id
@GeneratedValue
private Long id;
@Column(name="number")
private String number;
@ManyToOne(cascade=CascadeType.ALL)//多对一,设置级联
private Person p;
public Person getP() {
return p;
}
public void setP(Person p) {
this.p = p;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
}
实例5:只在多端配置映射并且设置级联,只保存一端
Person p = new Person();
p.setName("zhangsan");
Phone ph1 = new Phone();
Phone ph2 = new Phone();
ph1.setNumber("13109361111");
ph2.setNumber("13109362222");
ph1.setP(p);
ph2.setP(p);
session.save(p);
结果:
Hibernate:
insert
into
Person
(name, id)
values
(?, ?)
实例6.只在多端配置映射并且设置级联,只保存多端
Person p = new Person();
p.setName("zhangsan");
Phone ph1 = new Phone();
Phone ph2 = new Phone();
ph1.setNumber("13109361111");
ph2.setNumber("13109362222");
ph1.setP(p);
ph2.setP(p);
session.save(ph1);
session.save(ph2);
结果:Hibernate:
insert
into
Person
(name, id)
values
(?, ?)
Hibernate:
insert
into
Phone
(number, p_id, id)
values
(?, ?, ?)
Hibernate:
insert
into
Phone
(number, p_id, id)
values
(?, ?, ?)
先保存person,再保存phone,执行3条sql语句,运行结果完美
实例7.只在多端配置映射并且设置级联,先保存一端,再保存多端
Person p = new Person();
p.setName("zhangsan");
Phone ph1 = new Phone();
Phone ph2 = new Phone();
ph1.setNumber("13109361111");
ph2.setNumber("13109362222");
ph1.setP(p);
ph2.setP(p);
session.save(p);
session.save(ph1);
session.save(ph2);
结果:
Hibernate:
insert
into
Person
(name, id)
values
(?, ?)
Hibernate:
insert
into
Phone
(number, p_id, id)
values
(?, ?, ?)
Hibernate:
insert
into
Phone
(number, p_id, id)
values
(?, ?, ?)
运行同上,结果完美
实例7.只在多端配置映射并且设置级联,先保存多端,再保存一端
session.save(ph1);
session.save(ph2);
session.save(p);
结果:
Hibernate:
insert
into
Person
(name, id)
values
(?, ?)
Hibernate:
insert
into
Phone
(number, p_id, id)
values
(?, ?, ?)
Hibernate:
insert
into
Phone
(number, p_id, id)
values
(?, ?, ?)
运行同上,结果完美