删除休眠与多重关系

问题描述:

我的实体:删除休眠与多重关系

@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

这是我的解决方案。 首先,我将以这种方式在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