使用DiscriminatorColumn进行Hibernate JPA级联删除

时间:2014-01-06 18:51:29

标签: hibernate jpa hibernate-mapping cascade discriminator

我正在使用Hibernate的JPA实现。我有一个用户表,有不同类型的用户(私人|公共等..),user_type列指定用户的类型。

我有一个User类,它是一个表示用户表的实体。我添加了

@DiscriminatorColumn(name="user_type", discriminatorType=DiscriminatorType.STRING) 

在我的User类上创建了2个类,PrivateUser和PublicUser,每个类都使用相应的@DiscriminatorValue扩展User Class。

我还有PrivateCompany和PublicCompany表,它们分别使用一个名为company_id的列在用户表中使用一对多关系PrivateUser实体和PublicUser实体。我也在OneToMany关系上删除了Cascade。

现在,如果我有一个ID为10的PrivateCompany和一个ID为10的PublicCompany,以及PrivateCompany和PublicCompany的用户表中的用户条目,如下所示。

user_id | company_id | user_type
100       10           private
101       10           public

如果我删除PrivateCompany,我最终会删除用户101和100,因为one_ofMany关系在company_id上,并且它不考虑user_type列,尽管它被称为DiscriminatorColumn。我正在寻找一种方法来提供级联删除功能,该功能在删除子项时会占用DiscriminatorColumn。我尝试使用多列创建JoinColumns,但我可以创建与列名但不是列值的关系(这是我的情况)。

如果我的解释不明确,请告诉我。

提前致谢

2 个答案:

答案 0 :(得分:0)

据我了解,您的Company实体(PublicCompanyPrivateCompany)会映射到两个不同的表格。如果是这样,那么我还假设每家公司都有User的列表,而不是PrivateUserPublicUser的列表。 如果一切正确,那么你必须:

  1. 移除级联并手动处理。
  2. 更改公司实体中的列表/集合类型:而不是Collection<User>,而在PrivateCompany中需要Collection<PrivateUser>,在PublicCompany中需要Collection<PublicUser>
  3. 或者,为什么不简单地合并PrivateUser&amp; PublicUser在单个实体中+与公司实体相同并区分逻辑中的类型?

答案 1 :(得分:0)

我想通了,在PrivateUser类上添加了一个注释@SQLDelete,如下所示

@SQLDelete( sql="delete user WHERE private_company_id = ? and rel_type = 'private'")
public class PrivateUser extends User {

}

这样我就可以在PrivateCompany和PrivateUser的OneToMany关系上添加级联删除,但是当级联启动时,它会执行SQLDelete注释中提到的查询,让您可以控制。如果要将记录标记为非活动而不是删除,也可以使用此方法。

参考:Override default remove()/DELETE in JPA/Hibernate