I'm just trying to figure out if there's an elegant way to perform this mapping. I've got User, Team
& Department entities. Team and Department currently extend AbstractEntity (@MappedSuperclass)
which contains some common fields like Id, Name and some timestamp fields.
I want to have a many to many relationship between User and the Team and also the Department
entities to represent where a user is a manager of the Team or Department. A User could be a user
of one or more Teams and Departments.
I want to relationship to be bi-directional so that a Team and Department know who their managers
are and also each User knows which Teams and Departments they manage. It's this latter link that
I'm struggling to solve well, the link from the User entity to Teams and Departments.
Team and Departments don't have a common entity superclass so I'd have to have a link from the
User class to TeamThatIManage and DepartmentsThatIManage. In reality my entity structure is far
more complicated than this and there are five or six things that a user can manage. So there's quite
a lot of links from the User entity to other entities that a user can manage.
Is there any way I can model this with a single link from the User entity (i.e. ThingsThatIManage)
without using entity inheritance? I've been trying to avoid using entity inheritance because of the
performance hit on the table join. Just to be clear I mean that if I had an entity class
"ManagedThing" and Team and Department both extend ManagedThing then the User entity could
have a column private Collection<ManagedThing> thingsThatIManage, whereas at present I'd have
to have Collection<Team> teamThatIManage, Collection<Department> deptsThatIManage etc...
I'm pretty new to JPA and hope I'm not being completely stupid, any comments gratefully received.
Are the "Team", "Department", etc.. entities very similar? I am assuming there is a degree of over-lap if you are using a mapped superclass.
If so, my suggestion would be to put all types in a single (well managed!) table.
Doing this (and yes, using inheritance... but without the performance hit) you will have the table mapped in a base entity class (say, "Stuff"). Your table will contain an attribute that is a discriminator, probably an integer, to describe the type of that entry (eg, Team).
This base JPA mapping class will contain all of the table attributes that are common to all of your types.
After the @Entity and @Table annotations, include the following:
Then, each of your types (Team, Department, etc..) will be mapped w/ a class extending the base table. The class will be annotated with:
@DiscriminatorValue(<type int value>)
.. and the class will define all of the attributes which are not common to all types.
And finally, in the end, you will be able to have a List<Stuff> in, for example, your Team class. The discriminators are used to instantiate every "Stuff" item appropriately, so you will get back a list of Team, Department, etc... items.
The bi-directional mapping can be captured in a simple lookup table w/ <stuff item id>, <stuff item id> attributes.