Hibernate多对一ManytoOne

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

  

原文地址:https://www.cnblogs.com/beenupper/p/6810124.html