我对休眠延迟加载的复杂性有疑问。我有以下 4 个实体(简历 --> 证书、简历 --> 经验、简历 --> 教育):
@Table(name = "CV", schema = "recruiter")
public class CV extends TrackingEntity {
@Column(name = "RAW_FILE")
@Lob
private byte[] rawFile;
....
@OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.ALL })
private Set<Experience> experiences = new HashSet<Experience>();
@OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.ALL })
private Set<Education> educations = new HashSet<Education>();
@OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.ALL })
private Set<Certification> certifications = new HashSet<Certification>();
....
}
现在假设我们有一个正在运行的 Session 和一个正确初始化的 em,只需调用这段代码:
CV cv = createCV();// creates a new CV object with all children initialized
em.persist(t);
em.flush();
em.refresh(t);
有谁知道这里发生了什么?它将实体与子实体(插入语句)一起持久化,然后刷新实体(从数据库中选择子实体(经验、证书等)):
Hibernate: insert into recruiter.CV (version, CREATION_DATE, CREATION_USER, LAST_UPDATE_DATE, LAST_UPDATE_USER, FILE_NAME, FIRST_NAME, LAST_NAME, PREVIOUS_STATUS, RAW_FILE, STATUS) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into recruiter.CERTIFICATIONS (version, CREATION_DATE, CREATION_USER, LAST_UPDATE_DATE, LAST_UPDATE_USER, CV_ID, DATE_OBTAINED, NAME) values (?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into recruiter.CERTIFICATIONS (version, CREATION_DATE, CREATION_USER, LAST_UPDATE_DATE, LAST_UPDATE_USER, CV_ID, DATE_OBTAINED, NAME) values (?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into recruiter.CERTIFICATIONS (version, CREATION_DATE, CREATION_USER, LAST_UPDATE_DATE, LAST_UPDATE_USER, CV_ID, DATE_OBTAINED, NAME) values (?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into recruiter.EXPERIENCE (version, CREATION_DATE, CREATION_USER, LAST_UPDATE_DATE, LAST_UPDATE_USER, COMPANY_NAME, COMPANY_TYPE, CV_ID, END_DATE, START_DATE) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into CV_CERTIFICATIONS (CV_ID, certifications_ID) values (?, ?)
Hibernate: insert into CV_CERTIFICATIONS (CV_ID, certifications_ID) values (?, ?)
Hibernate: insert into CV_CERTIFICATIONS (CV_ID, certifications_ID) values (?, ?)
Hibernate: insert into CV_EXPERIENCE (CV_ID, experiences_ID) values (?, ?)
Hibernate: select certificat0_.ID as ID5_0_, certificat0_.version as version5_0_, certificat0_.CREATION_DATE as CREATION3_5_0_, certificat0_.CREATION_USER as CREATION4_5_0_, certificat0_.LAST_UPDATE_DATE as LAST5_5_0_, certificat0_.LAST_UPDATE_USER as LAST6_5_0_, certificat0_.CV_ID as CV9_5_0_, certificat0_.DATE_OBTAINED as DATE7_5_0_, certificat0_.NAME as NAME5_0_ from recruiter.CERTIFICATIONS certificat0_ where certificat0_.ID=?
Hibernate: select certificat0_.ID as ID5_0_, certificat0_.version as version5_0_, certificat0_.CREATION_DATE as CREATION3_5_0_, certificat0_.CREATION_USER as CREATION4_5_0_, certificat0_.LAST_UPDATE_DATE as LAST5_5_0_, certificat0_.LAST_UPDATE_USER as LAST6_5_0_, certificat0_.CV_ID as CV9_5_0_, certificat0_.DATE_OBTAINED as DATE7_5_0_, certificat0_.NAME as NAME5_0_ from recruiter.CERTIFICATIONS certificat0_ where certificat0_.ID=?
Hibernate: select certificat0_.ID as ID5_0_, certificat0_.version as version5_0_, certificat0_.CREATION_DATE as CREATION3_5_0_, certificat0_.CREATION_USER as CREATION4_5_0_, certificat0_.LAST_UPDATE_DATE as LAST5_5_0_, certificat0_.LAST_UPDATE_USER as LAST6_5_0_, certificat0_.CV_ID as CV9_5_0_, certificat0_.DATE_OBTAINED as DATE7_5_0_, certificat0_.NAME as NAME5_0_ from recruiter.CERTIFICATIONS certificat0_ where certificat0_.ID=?
Hibernate: select experience0_.ID as ID3_1_, experience0_.version as version3_1_, experience0_.CREATION_DATE as CREATION3_3_1_, experience0_.CREATION_USER as CREATION4_3_1_, experience0_.LAST_UPDATE_DATE as LAST5_3_1_, experience0_.LAST_UPDATE_USER as LAST6_3_1_, experience0_.COMPANY_NAME as COMPANY7_3_1_, experience0_.COMPANY_TYPE as COMPANY8_3_1_, experience0_.CV_ID as CV11_3_1_, experience0_.END_DATE as END9_3_1_, experience0_.START_DATE as START10_3_1_, projects1_.EXPERIENCE_ID as EXPERIENCE1_3_3_, project2_.ID as projects2_3_, project2_.ID as ID4_0_, project2_.version as version4_0_, project2_.CREATION_DATE as CREATION3_4_0_, project2_.CREATION_USER as CREATION4_4_0_, project2_.LAST_UPDATE_DATE as LAST5_4_0_, project2_.LAST_UPDATE_USER as LAST6_4_0_, project2_.ACTIVITY as ACTIVITY4_0_, project2_.DESCRIPTION as DESCRIPT8_4_0_, project2_.EXPERIENCE_ID as EXPERIENCE11_4_0_, project2_.NAME as NAME4_0_, project2_.ROLE as ROLE4_0_ from recruiter.EXPERIENCE experience0_ left outer join EXPERIENCE_PROJECT projects1_ on experience0_.ID=projects1_.EXPERIENCE_ID left outer join recruiter.PROJECT project2_ on projects1_.projects_ID=project2_.ID where experience0_.ID=?
Hibernate: select cv0_.ID as ID1_1_, cv0_.version as version1_1_, cv0_.CREATION_DATE as CREATION3_1_1_, cv0_.CREATION_USER as CREATION4_1_1_, cv0_.LAST_UPDATE_DATE as LAST5_1_1_, cv0_.LAST_UPDATE_USER as LAST6_1_1_, cv0_.FILE_NAME as FILE7_1_1_, cv0_.FIRST_NAME as FIRST8_1_1_, cv0_.LAST_NAME as LAST9_1_1_, cv0_.PREVIOUS_STATUS as PREVIOUS10_1_1_, cv0_.RAW_FILE as RAW11_1_1_, cv0_.STATUS as STATUS1_1_, certificat1_.CV_ID as CV1_1_3_, certificat2_.ID as certific2_3_, certificat2_.ID as ID5_0_, certificat2_.version as version5_0_, certificat2_.CREATION_DATE as CREATION3_5_0_, certificat2_.CREATION_USER as CREATION4_5_0_, certificat2_.LAST_UPDATE_DATE as LAST5_5_0_, certificat2_.LAST_UPDATE_USER as LAST6_5_0_, certificat2_.CV_ID as CV9_5_0_, certificat2_.DATE_OBTAINED as DATE7_5_0_, certificat2_.NAME as NAME5_0_ from recruiter.CV cv0_ left outer join CV_CERTIFICATIONS certificat1_ on cv0_.ID=certificat1_.CV_ID left outer join recruiter.CERTIFICATIONS certificat2_ on certificat1_.certifications_ID=certificat2_.ID where cv0_.ID=?
为什么 Hibernate 会执行 select 语句,因为这正是我试图通过延迟加载来避免的?