2014-11-08 179 views
0

我的實體:刪除休眠與多重關係

@Entity 
public class User{ 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "userId") 
    private Long id; 
    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL) 
    private List<UC> owned = new ArrayList<UC>(); 
} 

@Entity 
public class UC{ 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @JoinColumn(name = "ukId") 
    private Long id; 
    @ManyToOne(fetch = FetchType.EAGER) 
    @JoinColumn(name = "userId") 
    private User user; 
    @ManyToOne(fetch = FetchType.EAGER) 
    @JoinColumn(name = "catId") 
    private Cat cat; 
} 

@Entity 
public class Cat{ 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "catId") 
    private Long id; 
    @OneToMany(mappedBy = "cat", cascade = CascadeType.ALL) 
    private List<UC> owned = new ArrayList<UC>(); 
} 

因此,這裏是我的問題,實際上是少數人。

問題1:

我刪除,我給自己定cascadeType.All在貓的擁有列表上的貓對象,所以當我刪除貓對象的所有記錄在UC貓將被刪除,但是我得到「刪除的對象將被級聯重新保存」,這是因爲我在UC中有另一個關係到用戶,他將UC存儲在列表中。當我從UC中刪除Cat對象和記錄時,我不想刪除User對象,因此在UC中設置​​@ManyToOne級聯是一個禁忌。我應該怎麼做呢?在刪除Cat之前,我應該從用戶擁有的列表中刪除所有UC實例嗎?如果這種情況我必須從其他列表中刪除實例,那麼我在UC中的關係比在這裏顯示的要多。

問題2:

類似的情況,但我得到了許多普通到多的關係我想刪除連接表中的記錄,而不刪除關係的另一面。

+0

不知道,我完全明白了:你想刪除一個目錄實體,並自動刪除該貓UC表裏面的所有引用? – tigerjack89 2014-11-08 11:08:49

+0

是的,但沒有刪除關係中的用戶或其他實體。當我在UC內部不使用級聯時,我會在用戶被刪除時收到錯誤。我只想刪除Cat中的Cat,UC記錄並更新Cat的用戶列表。 – 2014-11-08 11:13:37

回答

0

這是我的解決方案。 首先,我將以這種方式在OneToMany關聯上設置孤兒刪除。

@OneToMany(mappedBy = "cat", cascade = CascadeType.ALL, orphanRemoval = true) 

然後,假設您有一個用戶u和一個想要刪除的Cat c。此代碼應該工作以及

// Remove a cat and update the other entities 
    Session s = sessionFactory.openSession(); 
    s.beginTransaction(); 
    s.delete(c); 
    for (UC uc : c.getOwned()) 
     uc.getUser().getOwned().remove(uc); 
    s.update(u); 
    s.getTransaction().commit(); 
    s.close(); 
+0

所以我從用戶中刪除所有UC的出現,但正如我所說,我與UC有更多的關係,這意味着我必須對所有其他集合進行此操作。這是否是正確的方式? – 2014-11-08 12:31:34

+0

好吧,如果您不想通過代碼執行此操作,則可以隨時強制命中數據庫以再次檢索用戶(集合已更新)。例如,你可以調用's.delete(c)',關閉會話,打開新會話並調用u = s.get(User.class,u.getId())'。要點是,當你調用's.delete(c)'時,它實際上刪除了UC表中所有的引用(即在數據庫上)。但是,本地收藏(即擁有的列表)不會自動更新。所以,如果你不想手動更新它,你必須重新打開數據庫(但我認爲這不是一個更好的解決方案tbh) – tigerjack89 2014-11-08 13:20:04

+0

@JohnSmith在答案代碼中,你也可以只做代理工作關於要刪除的實體(即cat c)並從其集合(即擁有的列表uc)中獲取對不應刪除的實體的引用(即用戶u)。 – tigerjack89 2014-11-08 13:44:03