title: Nested Hibernate Entity
body: <p>I am creating a Spring JPA (PostgresSQL &amp; H2) service that deals with offices.  I can have a stand-alone office, or an parent office (corporate) with children (remote) offices.  Offices have an address and a list of employees (who can belong to more than one office). I am struggling with the design and would really appreciate any help you can offer. </p>
  
  <p>My tables are currently in H2 for testing/dev so I don't have any referential integrity on the tables.<br>
  This is making me wonder if my model couldn't be improved.  Is there a better way to do this sort of recursive/nested relationship?</p>
  
  <p><strong>UPDATE</strong>
  Based on the excellent feedback from jfneis, I now have this approach:</p>
  
  <pre><code>@Entity
  @Inheritance(strategy = InheritanceType.SINGLE_TABLE)
  @DiscriminatorColumn(name = "OfficeType")
  @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "officeId")
  public abstract class Office {
  
      @Id
      @GeneratedValue(strategy = GenerationType.AUTO)
      @Column(name = "officeId", updatable = false, nullable = false)
      private long officeId;
  
      @Column
      private String name;
      @Column
      private String ein;
      @Column
      @Temporal(TemporalType.DATE)
      private Date startDate;
      @Column
      @Temporal(TemporalType.DATE)
      private Date endDate;
  
      @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
      @JoinColumn(name = "addressId", nullable = false)
      private Address address;
  
      @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
      @Fetch(value = FetchMode.SUBSELECT)
      private List&lt;Employee&gt; employees = new ArrayList&lt;&gt;();
  }
  </code></pre>
  
  <p>and the corporate office:</p>
  
  <pre><code>@Entity(name = "CorporateOffice")
  @DiscriminatorValue("Corporate")
  public class CorporateOffice extends Office {
  
      @Column
      private String url;
  }
  </code></pre>
  
  <p>and remote office:</p>
  
  <pre><code>@Entity(name = "RemoteOffice")
  @DiscriminatorValue("Remote")
  public class RemoteOffice extends Office {
  
      @ManyToOne(fetch = FetchType.EAGER)
      @JoinColumn(name = "corporateOfficeId")
      private Office corporateOffice;
  }
  </code></pre>
  
  <p>If I understand correctly, both office types will be stored in the "office" table with a column indicating which type it is.</p>
  
  <p>On startup I am seeding some test data so I can further see what is going on: </p>
  
  <pre><code>@Component
  @Transactional
  public class SeedOffices {
  
  @Autowired
  private OfficeRepository officeRepository;
  
  @PostConstruct
  public void seedOffices() {
      CorporateOffice corporate = new CorporateOffice();
      corporate.setName("World Domination Corp");
      corporate.setUrl("www.corporationsownstheworld.com");
      corporate.setStartDate(new Date());
      Address corpAddr = new Address();
      corpAddr.setAddressLine1("corp line 1");
      corpAddr.setCity("Denver");
      corporate.setEin("123456789");
      corporate.setAddress(corpAddr);
      officeRepository.save(corporate);
  
      RemoteOffice office1 = new RemoteOffice();
      office1.setStartDate(new Date());
      Address remote1Addr = new Address();
      remote1Addr.setAddressLine1("remote 1 line 1");
      remote1Addr.setCity("Cheyanne");
      office1.setAddress(remote1Addr);
      officeRepository.save(office1);
      office1.setCorporateOffice(corporate);
  
      RemoteOffice office2 = new RemoteOffice();
      Address remote2Addr = new Address();
      remote2Addr.setAddressLine1("remote 2 line 1");
      remote2Addr.setCity("Calumet");
      office2.setAddress(remote2Addr);
      officeRepository.save(office2);
      office2.setCorporateOffice(corporate);
  }
  </code></pre>
  
  <p>}</p>