title: How to map an abstract collection with jpa?
body: <p>I am trying to work out if it is possible get JPA to persist an abstract collection with concrete implementations.</p>
  
  <p>So far my code looks like this:</p>
  
  <pre><code>@Entity
  public class Report extends Model {
  
      @OneToMany(mappedBy = "report",fetch=FetchType.EAGER)
      public Set&lt;Item&gt; items;
  }
  
  @MappedSuperclass
  public abstract class OpsItem extends Model {
  
      @ManyToOne
      public RetailOpsBranch report;
  }
  
  
  @Entity
  @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
  public class AItem extends OpsItem {
  ...
  }
  
  @Entity
  @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
  public class BItem extends OpsItem {
  ...
  }
  </code></pre>
  
  <p>But I keep stumbling on the mapping error below and I don't really know if this is feasible?</p>
  
  <pre><code>JPA error
  A JPA error occurred (Unable to build EntityManagerFactory): Use of @OneToMany or
  @ManyToMany targeting an unmapped class: models.Report.items[models.OpsItem]
  </code></pre>
  
  <p><strong>UPDATE</strong></p>
  
  <p>I don't think the problem is with the abstract class but the the <strong>@MappedSuperClass</strong> annotation.
  It looks like jpa does not like to map the one to many relationship with a <strong>@MappedSuperClass</strong>.
  If I change the abstract class into a concrete class I have the same error. </p>
  
  <p>If I then change to <strong>@Entity</strong> annotation this seem to work with both the abstract and concrete class.</p>
  
  <p>This seems a bit strange to map an abstract class with <strong>@Entity</strong>.
  I'm I missing anything?</p>
  
  <p><strong>SOLUTION</strong></p>
  
  <p>Managed to figure it out with the help from rhinds.
  Two points to note:</p>
  
  <p>1) the abstract class needs to be annotated with @Entity and inheritance strategy of table per class for the subclasses to have their own table.</p>
  
  <p>2) Identity Id generation will not work in this scenario and I had to use Table generation type.</p>
  
  <pre><code>@Entity
  @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
  public abstract class OpsItem extends GenericModel {
  
      @Id
      @GeneratedValue(strategy = GenerationType.TABLE)
      public Long id;
  
      public String          branchCode;
  
      @ManyToOne
      public Report report;
  }
  
  @Entity
  @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
  public class AItem extends OpsItem {
  ...
  }
  </code></pre>