2014-07-04 47 views
1

我有一個包含評論列表的Story,與JoinTable映射。 我注意到,每次我給列表添加一個新評論時,hibernate刪除並重新創建與故事相關的連接表中的所有條目。 我希望它只是添加一個新的表格。 在下面的代碼中,保存方法由Spring Data實現。 我錯過了什麼嗎? 謝謝。當添加到列表時,Hibernate重新創建連接表

Story.java:

@Entity 
public class Story implements Serializable { 
    @OneToMany 
    @JoinTable(name="UserComment", joinColumns = @JoinColumn(name = "Story_id"), inverseJoinColumns = @JoinColumn(name = "Comment_id")) 
    private List<Comment> userComments; 
    ... 

Comment.java:

@Entity 
public class Comment implements Serializable { 
... 

添加一個新評論:

Comment comment = new Comment(); 
comment.setContent(content); 
commentRepository.save(comment); 
story.getUserComments().add(comment); 
storyRepository.save(story); 

Hibernate的日誌上storyRepository.save(故事)執行:

Hibernate: delete from UserComment where Story_id=? 
Hibernate: insert into UserComment (Story_id, Comment_id) values (?, ?) 
Hibernate: insert into UserComment (Story_id, Comment_id) values (?, ?) 
Hibernate: insert into UserComment (Story_id, Comment_id) values (?, ?) 
Hibernate: insert into UserComment (Story_id, Comment_id) values (?, ?) 
Hibernate: insert into UserComment (Story_id, Comment_id) values (?, ?) 
Hibernate: insert into UserComment (Story_id, Comment_id) values (?, ?) 
Hibernate: insert into UserComment (Story_id, Comment_id) values (?, ?) 

庫版本:

  • 的Hibernate 4.3.5
  • 春數據JPA 1.6.0

回答

2

這是使用單向袋的預期行爲。根據[休眠反模式] [1]:

袋語義有表現最差的,當涉及到的 數量的操作,因爲它總是重新創建整個集合。 Hibernate發出刪除語句以從關聯表中刪除舊集合的所有關聯。然後,它發出N個插入 以將表示新集合的所有關聯添加到 關聯表中。休眠不會分析集合中有多少個元素已被更改 。

  1. 你可以把它變成一個ID包,這是一個索引列表優化。
  2. 您可以將具有2個@ManyToOne關聯的UserComment映射映射到Story和Comment,這樣您的包就會變成一個mappedBy雙向包,比單向包更有效率(因爲mappedBy包不會控制關聯,因爲它將@ManyToOne方傳播到SQL語句的狀態轉換)。
+0

我是唯一一個認爲,有這麼多問題,我們應該沒有hibernate管理的關聯更好?我將編寫一個簡單的本地查詢來將註釋添加到列表中。 – xtian

+1

我的建議是保持簡單。 –

+0

就像編寫我自己的查詢一樣簡單,爲什麼我應該更改我的模型以適應持久性引擎特性? @Query(value =「insert into UserComment(Story_id,Comment_id)VALUES(:storyId,:commentId)」,nativeQuery = true) – xtian

相關問題