Entity的OneToMany映射(MySQL數據庫)

小夥伴被OneToMany映射折騰的夠慘,楞是用不明白。主表ID主鍵並沒有如願以償作爲附表的外鍵,並且在保存主entity時還報錯,說是附表的外鍵列不能爲空…

我想,Hibernate不可能這麼弱,肯定是用得不對。一頓搜索一頓琢磨,在MySQL數據庫下,要這麼做才行:

  1. 數據庫層面,附表,即OneToMany的Many方在外鍵列上首先創建索引,然後添加外鍵,如下所示。一個job包含多個case,那麼job_info就是主表,job_case就是附表。job_case附表裏job_id列是外鍵,指向job_info主表的id列。
alter table job_case add index (jobId)
alter table job_case add foreign key (jobId) references job_info(id)
  1. 在主表的entity類裏,添加List< JobCase >域,並且添加OneToMany註解和JoinColumn註解.
  • 2.1 OneToMany註解,需要注意FetchType,如不註明採用Eager模式,就會走Lazy模式,這時entity類最好加上@Transactional註解,保持session,否則後面用到List<JobCase>會報錯,沒有transaction manager,無法連接DB查詢關聯的JobCase數據。
  • 2.2 JoinColumn註解,name屬性指的是附表外鍵列的列名(不是附表entity類的域名,是數據庫裏附表的外鍵列列名額)
  • 2.3 JoinColumn註解,referencedColumnName指的是數據庫主表作爲附表外鍵的那個列名,同第一步裏爲附表建外鍵時references job_info(id)是一個道理
  • 2.4 JoinColumn註解裏nullable設爲true
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
@JoinColumn(name="jobId", referencedColumnName = "id", nullable = true)
private List<JobCase> caseList = new ArrayList<>();
  1. 在附表entity類的,外鍵列要設置成insertable = false, nullable = true,注意檢查DB表對應列的設置,也是可爲空纔可以,這個設置非常關鍵…
@Column(name = "jobId", insertable = false, nullable = true)
private long jobId;

爲什麼附表的外鍵列設置成nullable纔可以呢,不科學啊,外鍵一般不應該可以爲空的呀…

我想了想,是這樣的,一般MySQL數據庫裏,表的ID列在建表時都設置成了自增的,Hibernate在保存記錄到數據庫裏時,它預先生成好的insert sql(OneToMany映射下,主表一條insert語句,附表0至多條insert語句)裏是沒辦法寫id值的,只能是在insert會後DB會給表的ID列寫入一個自增值。我大膽猜測,Hibernate肯定是根據自己生成的Insert語句,先insert主表,再insert附表,最後去拿主表的id值,update到附表的外鍵裏去。所以附表的外鍵列必須是insertable=false, nullable = true…

因吹斯汀!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章