FetchType
FetchType.LAZY
延迟加载,在查询实体A时,不查询出关联实体B,在调用getxxx方法时,才加载关联实体,但是注意,查询实体A时和getxxx必须在同一个Transaction中,不然会报错:no session
FetchType.EAGER
饥饿加载,在查询实体A时,查询出关联的实体B
CascadeType
CascadeType.PERSIST
只有A类新增时,会级联B对象新增。若B对象在数据库存(跟新)在则抛异常(让B变为持久态)
CascadeType.MERGE
指A类新增或者变化,会级联B对象(新增或者变化)
CascadeType.REMOVE
只有A类删除时,会级联删除B类;
CascadeType.ALL
包含所有;
CascadeType.REFRESH
级联刷新:获取order对象里也同时也重新获取最新的items时的对象。对应EntityManager的refresh(object)方法有效。即会重新查询数据库里的最新数据
综上:大多数情况用CascadeType.MERGE就能达到级联跟新又不报错,用CascadeType.ALL时要斟酌下CascadeType.REMOVE
Refresh的作用:假如有一个条数据(就有name[值为B]和sex[值为male]两个字段),A用户取出来在进行修改操作(修改name为A),正在A修改的过程中(未提交表单),B用户也对这条数据进行修改操作(修改sex为female),B先将性别修改后提交数据库...接着A用户也提交表单,但是,此时在entityManager中的持久化实体的性别为male,没有更新为B用户修改成的female,所以此时执行一次Refresh操作,就会将该实体更新为数据库中的最新记录,然后再进行提交..做级联的时候就会将关联的实体的也获取最新的然后在更新,前提是要执行Refresh操作,CasCadeType.Refresh才会生效
Merge的作用:你要先去了解持久化实体在entityManager中的几种状态,新建,游离,托管(不是脱管),删除状态,Merge对实体进行操作时,会区分这个实体的状态,假如这个实体处于托管状态,就应该使用merge,否则会报异常..同样,做级联的时候执行merge操作,CasCadeType.Merge也会对关联实体生效
@OneToMany
用于标记一对多的实体映射关系
方案1
主控方在A表,针对A的操作会级联操作B表,执行过程,插入A,插入B,在更新B中的user_id字段.
A:
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private List address;
B:
@ManyToOne(cascade = {CascadeType.PERSIST,CascadeType.MERGE}, fetch = FetchType.EAGER)
private User user;
方案2
主控方在B表,针对B的操作会级联插入A表,执行过程,插入A,插入B,此时已经包含了A生成的id对应user_id
A:
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "user")
private List address;
B:
@ManyToOne(cascade = {CascadeType.PERSIST,CascadeType.MERGE}, fetch = FetchType.EAGER)
方案3
使用@JoinTable双向控制
A:
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinTable(name = "user_address", joinColumns = { @JoinColumn(name = "ref_user_id") }, inverseJoinColumns = { @JoinColumn(name = "ref_address_id") })
private List address;
B:
@ManyToOne(cascade = {CascadeType.PERSIST,CascadeType.MERGE}, fetch = FetchType.EAGER)
@JoinTable(name = "user_address", joinColumns = { @JoinColumn(name = "ref_address_id") }, inverseJoinColumns = { @JoinColumn(name = "ref_user_id") })
private User user;