Two entities coexisting in one table

I have stumbled across small problem. I had an abstract class, which aggregated all mutual properties of an object and two concrete classes. One did not need any additional fields, while the other needed another relation. Idea was to create one table and gather both those concrete objects from it. I have never done it before, so it was interesting thing to discover.

I was working on Team abstraction. Team is a collection of heroes. But teams can be lead by someone or self-organized, hence I have three classes, like so:
import java.util.Collection;
import javax.persistence.ManyToMany;
import javax.persistence.MappedSuperclass;
import javax.persistence.OneToMany;
import weapon.rental.BaseEntity;
import weapon.rental.hero.domain.Hero;
import weapon.rental.invitation.Invitation;
@MappedSuperclass
public abstract class BaseTeam extends BaseEntity {
private String name;
@ManyToMany
private Collection<Hero> heroes;
@OneToMany
private Collection<Hero> pending;
@OneToMany
private Collection<Invitation> invitations;
@OneToMany
private Collection<Hero> banned;
public int heroesAmount() {
return heroes.size();
}
}
view raw 1BaseTeam.java hosted with ❤ by GitHub
import javax.persistence.Entity;
import javax.persistence.Table;
@Entity(name = "Team")
@Table(name = "Team")
public class Team extends BaseTeam {
}
view raw 2Team.java hosted with ❤ by GitHub
import java.util.Collection;
import javax.persistence.Entity;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import weapon.rental.hero.domain.Hero;
@Entity(name = "Team")
@Table(name = "Team")
public class LeadTeam extends BaseTeam {
@OneToMany
private Collection<Hero> leaders;
}
view raw 3LeadTeam.java hosted with ❤ by GitHub

Notes:

  • BaseTeam is an abstract class annotated with @MappedSuperclass. Since it is abstract I cannot instantiate it and with annotation all its properties will be passed to class extending it.
  • Team class is a concrete class extending BaseTeam. It inherits all the properties from its superclass and does not define any new. It is annotated with @Entity and @Table with filled name property.  It is important to fill those properties, so concrete class can recognize themselves as one column in database.
  • LeadTeam adds some new relation and is also annotated with @Entity and @Table in the same manner as Team class.
What will hibernate do with such a classes? It will create just one table called "Team", and it will be possible to get both instances of Team. 

The database looks like this:


Side note:

Without setting up same names of entities Hibernate thought I want to host two different entities in one table, therefore it created additional column dtype - discriminator, to recognize between two types. It does not suite my case, so I wanted to avoid it, but it's good to know why such a new column can be created.

Komentarze

Popularne posty z tego bloga

Java EE 8 & Wildfly 17 & RestEasy setup

Optional finallyLearned()

Testing: jUnit's TemporaryFolder