Estoy tratando de usar JPA 2.0 para crear entidades polimórficas con relaciones genéricas. Debe haber dos tablas, una tabla de eventos y una tabla de notificaciones. Dentro de los tabla son entidades concretas que están relacionados entre sí, así:Cómo implementar entidades JPA polimórficas con relaciones genéricas
Event <---------- Notification<X extends Event>
| |
LoginEvent <------ LoginNotification extends Notification<LoginEvent>
Lógicamente, esto debería ser posible en hibernación, ya que es posible en SQL:
+----------+ +----------+
| Event | | Notif |
+----------+ +----------+
| | | Id |
| Id | <- | Evt_id |
| Type | <- | Type |
| ... | | ... |
+----------+ +----------+
Esto es lo que tengo :
@Entity
@Inheritance
public abstract class Event{
...
}
@Entity
public class LoginEvent extends Event{
...
}
@Entity
@Inheritance
public abstract class Notification<X extends Event>{
@ManyToOne(optional=false, targetEntity=Event.class)
@JoinColumn
private X event;
...
}
@Entity
public class LoginNotification extends Notification<LoginEvent>{
...
}
Usando este código, que puede persistir a buscar cualquier caso, notificación, LoginEvent o NotificationEvent, pero se cae cuando trato de usar la relación LoginNotification_.event
en mis consultas de metamodelo JPA 2.0. This issue explica algo similar.
public static volatile SingularAttribute<NotificationEntity, EventEntity> event;
Cuando intento hacer una combinación en una consulta criterios, me sale un error:
EntityManager em = getEntityManager();
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<LoginNotification> query = cb.createQuery(LoginNotification.class);
Root<LoginNotification> root = query.from(LoginNotification.class);
// This line complains: Type mismatch: cannot convert from
// Join<LoginNotification,Event> to Join<LoginNotification,LoginEvent>
Join<LoginNotification, LoginEvent> join =
root.join(LoginNotification_.event, JoinType.INNER);
puedo solucionar este error, mediante la adición de un nuevo SingularAttribute
a la LoginNotification_
metamodelo, pero esto falla en la ejecución:
public abstract class LoginNotification_ extends Notification_ {
// Adding this Removes Type mismatch error, but causes run-time error
public static volatile SingularAttribute<LoginNotification, LoginEvent> event;
...
}
de acuerdo con algunos mensajes, las relaciones genérico no funcionará (How to handle JPA annotations for a pointer to a generic interface), pero mediante el uso de un @ManyToOne(optional=false, targetEntity=Event.class)
una notación, podemos hacer que se comporten. Desafortunadamente, los genéricos parecen romper la consulta de criterios de JPA.
¿Hay alguna sugerencia sobre cómo puedo realizar esta búsqueda? Puedo usar LoginNotification.getEvent()
en mi código, pero no puedo usar LoginNotification_.event
en las combinaciones de mi metamodelo JPA. ¿Cuál es la alternativa al uso de genéricos para lograr esto?
@Pascal Thivent - ¿Puedes responder esto?
Excelente, solía escribir mi se une de esta manera en SQL de todos modos. – logan