Sto cercando di utilizzare JPA 2.0 per creare entità polimorfiche con relazioni generiche. Dovrebbero esserci due tabelle, una tabella eventi e una tabella di notifica. All'interno coloro tabella sono entità concrete che sono legati gli uni agli altri, in questo modo:Come implementare entità polimorfiche JPA con relazioni generiche
Event <---------- Notification<X extends Event>
| |
LoginEvent <------ LoginNotification extends Notification<LoginEvent>
Logicamente questo dovrebbe essere possibile in ibernazione, in quanto è possibile in SQL:
+----------+ +----------+
| Event | | Notif |
+----------+ +----------+
| | | Id |
| Id | <- | Evt_id |
| Type | <- | Type |
| ... | | ... |
+----------+ +----------+
Questo è ciò che ho :
@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>{
...
}
Utilizzando questo codice, posso persistere e recuperare ogni caso, notifica, LoginEvent o NotificationEvent, ma cade quando si tenta di utilizzare la relazione LoginNotification_.event
nelle mie query sui metamodelli JPA 2.0. This issue spiega qualcosa di simile.
public static volatile SingularAttribute<NotificationEntity, EventEntity> event;
Quando provo a fare un join in una query criteri, ottengo un errore:
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);
posso ottenere intorno a questo errore, con l'aggiunta di un nuovo SingularAttribute
al LoginNotification_
metamodello, ma questo non riesce in esecuzione:
public abstract class LoginNotification_ extends Notification_ {
// Adding this Removes Type mismatch error, but causes run-time error
public static volatile SingularAttribute<LoginNotification, LoginEvent> event;
...
}
Secondo alcuni messaggi, rapporti generici non funziona (How to handle JPA annotations for a pointer to a generic interface), ma utilizzando un @ManyToOne(optional=false, targetEntity=Event.class)
un notazione, possiamo farli comportare. Sfortunatamente, i generici sembrano rompere la query sui criteri JPA.
Ci sono suggerimenti su come posso eseguire questa ricerca? Posso usare LoginNotification.getEvent()
nel mio codice, ma non posso usare LoginNotification_.event
nei miei join Metamodel JPA. Qual è l'alternativa all'uso dei generici per realizzare questo?
@Pascal Thivent - Puoi rispondere a questo?
eccellente, ho usato per scrivere il mio si unisce in questo modo in SQL comunque. – logan