------------------------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 (?, ?, ?) 运行同上,结果完美