2016-02-05 64 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的插入语句的一部分。