2013-08-07 94 views
2

我有一類用戶包括書籍對象列表。一旦創建了用戶的記錄,他借用的所有書籍都將添加到他的對象中的書籍列表中。一旦用戶刪除他的檔案,需要保存借來的書籍的記錄和歷史記錄。我的代碼拋出org.hibernate.ObjectDeletedException異常

許多註冊用戶可能經常借書並刪除他們的個人資料。爲了使信息檢索速度更快(例如,檢索活動用戶列表),我不希望將已刪除配置文件的記錄保存在保留活動配置文件記錄的同一個表中。

目前一旦用戶想要刪除他的個人資料,我把這個對象(userObj)放在deactiveUserObj中,並從User表中刪除用戶的記錄,並嘗試保存deactiveUserObj以保留該表中停用記錄的記錄,但它會引發以下例外。

我的選擇:我知道我可以創建另一個表,並保持活躍用戶的ID存在或有boolean類型的用戶類的一個額外的列,使其false指示記錄被刪除。但我不確定這三種方法哪一種更好,或者是否有另一種我沒有考慮過的方法。

用戶類

@Entity 
public class User{ 

    private long id; 
    private List<Book> books; 
    ... 

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) 
    public List<Book> getBooks() { 
     return books; 
    } 
    .... 

Book類

@Entity 
public class Book{ 

    private long id; 
    private string name; 
    ... 
} 

刪除的對象類

@Entity 
public class DeactiveUsers{ 

    private long id; 
    private date deactiveSince; 
    private List<Book> books; 
    ... 

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) 
    public List<Book> getBooks() { 
     return books; 
    } 
    ....  

} 

mycode的

1) code to retrieve an object of user class goes here 
2) code to copy object of user class into deletedObject goes here 
3) 3.1 - session.delete(userObj); 
    3.2 - session.saveOrUpdate(deactiveUsersObj); 

的代碼運行到以下錯誤

SEVERE: org.hibernate.ObjectDeletedException: deleted object would be re-saved by 
     cascade (remove deleted object from associations): [com.project.Book#1] 

回答

2

第一:之所以你的錯誤是你必須級聯設置爲全上User.getBooks(),這將刪除書籍時您刪除用戶。然後,在同一個會話中,當您添加DeactivatedUser(包含相同的書籍)時,您嘗試重新添加已刪除的對象 - 雖然您未顯示用於從用戶構建DeactivatedUser的代碼,但我認爲您是製作書籍的淺層副本,如你所願)。將級聯更改爲SAVE_UPDATE。

二:我強烈建議讓他們都在同一個表的標誌字段,表示如果他們被刪除或沒有。

不要過早優化。除非您已經對代碼進行了基準測試,發現與活動用戶和非活動用戶相關的數據庫查詢存在瓶頸,否則過度複雜化模式和業務邏輯沒有任何好處。大多數SQL服務器非常高效,您不太可能在應用程序中發現瓶頸。

這樣做,這樣,一個簡單的方法來提高性能是簡單地創建被刪除的標誌字段的索引。

使用Hibernate,您將可以通過標準輕鬆選擇活動與已刪除的用戶。

此外,最重要的是,通過沒有單獨的User和DeactiveUser對象,您不必同時維護這兩個對象,也不必重複可以在兩種類型上運行的代碼。

+0

如果需要爲單個用戶配置多個配置文件,那麼該怎麼辦?並需要檢索那些活動? –

+1

你的數據庫模式應該反映你正在處理的對象。如果每個用戶需要多個配置文件,那麼您需要一個單獨的配置文件對象,配置文件的單獨表以及一對多的用戶配置文件關係(將一組一對多的配置文件放入用戶,以及配置文件中的多對一用戶字段)。 Hibernate的HQL查詢將允許您根據關聯用戶中的字段選擇配置文件,例如'session.createQuery(「來自Profile p,其中p.user.active = true」)''。它會爲您生成一個交叉連接(默認情況下)的查詢。 –