2016-02-05 129 views
1

我面臨的情況與this question一樣,沒有有用的答案。如何避免Hibernate使用OneToMany生成兩個查詢更新?

當我將一個新元素添加到我的一對多關係的很多部分時,Hibernate會生成兩個查詢,一個用於插入,另一個用於將外鍵更新爲父項。

爲什麼需要第二個查詢?插入中是否設置了父代的ID? 有什麼辦法可以避免這種情況?

Hibernate: 
     /* insert mydomain.LanguageKnowledge */ 
      insert 
      into 
       languageKnowledge 
       (language_fk, level_fk, personId_fk) 
      values 
       (?, ?, ?) 
    Hibernate: 
     /* create one-to-many row mydomain.Person.offeredLanguages */ 
     update 
      languageKnowledge 
     set 
      personId_fk=? 
     where 
      id=? 



    public class LanguageKnowledge { 

     @Id 
     @GeneratedValue(strategy = IDENTITY) 
     private Integer id; 

     @Enumerated(STRING) 
     @Column(name = "language_fk") 
     private LanguageIso639_3 language; 

     @Enumerated(STRING) 
     @Column(name = "level_fk") 
     private LanguageLevel level; 

     protected LanguageKnowledge() { 
     } 
    } 


    public class Person { 

     @Id 
     @GeneratedValue(strategy = IDENTITY) 
     private Integer id; 

     @OneToMany(fetch = EAGER, cascade = {ALL}, orphanRemoval = true) 
     @JoinColumn(name = "personId_fk", referencedColumnName = "id", nullable = false) 
     private final Set<LanguageKnowledge> offeredLanguages = new HashSet<>(); 

     public Person(Set<LanguageKnowledge> offeredLanguages) { 
      addOfferedLanguages(offeredLanguages); 
     } 

     protected Person() { 
     } 

     public void addOfferedLanguages(Set<LanguageKnowledge> offeredLanguages) { 
      this.offeredLanguages.addAll(offeredLanguages); 
     } 

     public void removeOfferedLanguages(Set<LanguageKnowledge> offeredLanguagesToRemove) { 
      this.offeredLanguages.removeAll(offeredLanguagesToRemove); 
     } 
    } 
+0

你想避免哪個查詢?這兩個看起來很有用.... –

+0

@JordiCastilla第二個,更新。編輯我的問題。 – mark951131b

回答

1

該協會是單向的,所以Person是擁有方(因爲它是唯一的一側)。

使聯想雙向,並使LanguageKnowledge聯想的所有者。這樣您將避免多餘的更新,因爲外鍵值將被指定爲LanguageKnowledge的插入語句的一部分。