title: How to implement polymorphic JPA entities with generic relations
body: <p>I'm trying to use JPA 2.0 to create polymorphic entities with generic relations. There should be two tables, an event table and a notification table. Inside those table are concrete entities that are related to one another, like so:</p>
  
  <pre><code>Event  &lt;---------- Notification&lt;X extends Event&gt;
   |                      |
  LoginEvent &lt;------ LoginNotification extends Notification&lt;LoginEvent&gt;
  </code></pre>
  
  <p>Logically this should be possible in hibernate, as it is possible in SQL:</p>
  
  <pre><code>+----------+    +----------+
  | Event    |    | Notif    |
  +----------+    +----------+
  |          |    | Id       |
  | Id       | &lt;- | Evt_id   |
  | Type     | &lt;- | Type     |
  | ...      |    | ...      |
  +----------+    +----------+
  </code></pre>
  
  <p>This is what I have:</p>
  
  <pre><code>@Entity
  @Inheritance
  public abstract class Event{
  
  ...
  }
  
  @Entity
  public class LoginEvent extends Event{
  
  ...
  }
  
  @Entity
  @Inheritance
  public abstract class Notification&lt;X extends Event&gt;{
  
   @ManyToOne(optional=false, targetEntity=Event.class)
   @JoinColumn
   private X event;
  
  ...
  }
  
  @Entity
  public class LoginNotification extends Notification&lt;LoginEvent&gt;{
  
  ...
  }
  </code></pre>
  
  <p>Using this code, I can persist and fetch any Event, Notification, LoginEvent, or NotificationEvent, but it falls down when I try to use the <code>LoginNotification_.event</code> relation in my JPA 2.0 metamodel queries. <a href="http://opensource.atlassian.com/projects/hibernate/browse/METAGEN-29" rel="noreferrer">This issue</a> explains something similar.</p>
  
  <pre><code>public static volatile SingularAttribute&lt;NotificationEntity, EventEntity&gt; event;
  </code></pre>
  
  <p>When I try to do a join in a criteria query, I get an error:</p>
  
  <pre><code>EntityManager em = getEntityManager();
  CriteriaBuilder cb = em.getCriteriaBuilder();
  CriteriaQuery&lt;LoginNotification&gt; query = cb.createQuery(LoginNotification.class);
  Root&lt;LoginNotification&gt; root = query.from(LoginNotification.class);
  
  //  This line complains: Type mismatch: cannot convert from
  //  Join&lt;LoginNotification,Event&gt; to Join&lt;LoginNotification,LoginEvent&gt;
  Join&lt;LoginNotification, LoginEvent&gt; join = 
  root.join(LoginNotification_.event, JoinType.INNER);
  </code></pre>
  
  <p>I can get around this error, by adding a new <code>SingularAttribute</code> to the <code>LoginNotification_</code> metamodel, but this fails in execution:</p>
  
  <pre><code>public abstract class LoginNotification_ extends Notification_ {
  
      // Adding this Removes Type mismatch error, but causes run-time error
      public static volatile SingularAttribute&lt;LoginNotification, LoginEvent&gt; event; 
  
      ...
  }
  </code></pre>
  
  <p>According to some posts, generic relations won't work (<a href="http://stackoverflow.com/questions/2808251/how-to-handle-jpa-annotations-for-a-pointer-to-a-generic-interface">How to handle JPA annotations for a pointer to a generic interface</a>), but by using a <code>@ManyToOne(optional=false, targetEntity=Event.class)</code> annotation, we can get them to behave. Unfortunately, the generics seem to break the JPA criteria query.</p>
  
  <p>Are there any suggestions on how I can perform this lookup? I can use <code>LoginNotification.getEvent()</code> in my code, but I cannot use <code>LoginNotification_.event</code> in my JPA metamodel joins. What's the alternative to using generics to accomplish this?</p>
  
  <p>@Pascal Thivent - Can you answer this?</p>