2014-04-01 26 views
0

我有使用策略GenerationType.TABLE生成的ID的父級和子級實體,因爲我正在使用MySQL數據庫。爲什麼Hibernate使用序列

如果我在沒有指定ID的情況下創建父項(即,首次創建父項),請向其中添加新的子項並保存父項,然後hibernate按預期方式工作並使用MySQL AUTO_INCREMENT列功能。但是,如果我創建了一個父項並指定了一個ID(例如,實例化了一個已經被保留的父項),那麼向它添加一個子項並保存該子項,然後休眠問題發出select sequence_next_hi_value from hibernate_sequences ...並將其用作孩子的PK。同樣,如果我通過session.get(Parent, 1)從數據庫中獲取父實例化一個父對象,向它添加一個新的子對象,然後保存父對象或子對象,然後hibernate使用序列來獲取對象的PK。

如果我創建了足夠的新父母(準確地說是32767)來運行mysql AUTO_INCREMENT計數器,那麼由於主鍵不夠獨特而導致失敗。

這裏是我的父母和孩子的實體(名爲位置和類別,分別對應)

@Entity(name="location") 
public class Location { 
    @Id @GeneratedValue(strategy=GenerationType.TABLE) @Column(name="location_id") 
    private int id; 

    @OneToMany(mappedBy="location") 
    @Cascade(CascadeType.SAVE_UPDATE) 
    private List<Category> categories; 

    ... 
} 

@Entity(name="category") 
public class Category { 
    @ID @GeneratedValue(strategy=GenerationType.TABLE) @Column(name="category_id") 
    private int id; 

    @ManyToOne @JoinColumn(name="location_id") 
    private Location location; 
} 

下面是Hibernate代碼:

Hibernate: select sequence_next_hi_value from hibernate_sequences where sequence_name = 'category' for update 
Hibernate: update hibernate_sequences set sequence_next_hi_value = ? where sequence_next_hi_value = ? and sequence_name = 'category' 
Hibernate: insert into category (location_id, category_id) values (?, ?) 

回答

0

在此之前我沒有答案,爲什麼Hibernate使用另一當堅持你的孩子記錄時的策略。但我可能會給你一些關於你所描述的其他問題的答案或提示:

關於策略GenerationType.TABLE,你的應用程序依賴於生成一個ID的數據庫功能。這可能會導致插入的每個新數據庫記錄的數據庫往返行程。當使用像hi-lo這樣的替代策略時,生成器將通過僅與數據庫聯繫一次來保留一堆ID(例如100或1000)。這可能會大大提高性能。另一方面,當應用程序重新啓動時,您可能會丟失一些ID。如果你可能會考慮這個問題hi-lo的生活。

使用不依賴於數據庫產品的策略的另一個好處是,如果切換數據庫,您可能會保留映射。

相關問題