Question

I am using Hibernate's implementation of JPA. I have a user table with different types of users(Private | Public etc..), the user_type column specifies the types of the user.

I have a User class which is an entity that represents user table. I added

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

on my User class and created 2 classes, PrivateUser and PublicUser each of them extending User Class with corresponding @DiscriminatorValue.

I also have PrivateCompany and PublicCompany tables which has one to many relationship PrivateUser entity and PublicUser entity respectively using a column called company_id in user table. I also have a Cascade delete on both OneToMany Relationships.

Now if I have a PrivateCompany with id 10 and a PublicCompany with ID 10 and user entries in user table for both PrivateCompany and PublicCompany like the following.

user_id | company_id | user_type
100       10           private
101       10           public

If I delete the PrivateCompany, I am ending up deleting user 101 along with 100 because the OneToMany relationship in on company_id and it does not consider the user_type column despite its mention as DiscriminatorColumn. I am looking for a way to give cascade delete functionality which accounts DiscriminatorColumn while deleting the children. I tried to create JoinColumns with multiple columns, but I can create the relationship with column name but not column value(which is my case).

Please let me know if my explanation is not clear.

Thanks in advance

Was it helpful?

Solution 2

I figured it out, on PrivateUser class add a annotation @SQLDelete like the following

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

}

This way I can add cascade delete on OneToMany Relationship of PrivateCompany and PrivateUser, but when cascade kicks in, it executes the query mentioned in SQLDelete annotation giving you control. This approach can also be used if you want to mark a record as inactive instead of deleting it.

Reference: Override default remove()/DELETE in JPA/Hibernate

OTHER TIPS

As I understand, your Company entities (PublicCompany and PrivateCompany) are mapped to two different tables. If so, then I also suppose that every company has a list of User, and not of PrivateUser or PublicUser. If everything is correct, then you must:

  1. either remove the cascading and handle that manually.
  2. change the type of List/Collection in your Company entities: instead of Collection<User> you need Collection<PrivateUser> in PrivateCompany and Collection<PublicUser> in PublicCompany.

Alternatively why not simply merge PrivateUser & PublicUser in a single entity + the same with the Company entity and differentiate the types in your logic?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top