2011-01-02 14 views
14

Genel ilişkilerle polimorfik varlıklar oluşturmak için JPA 2.0 kullanmaya çalışıyorum. İki tablo, bir olay tablosu ve bir bildirim tablosu olmalıdır. o SQL mümkün olduğu gibi,Genel ilişkilerle polimorfik JPA varlıkları nasıl uygulanır?

Event <---------- Notification<X extends Event> 
|      | 
LoginEvent <------ LoginNotification extends Notification<LoginEvent> 

Mantıken bu hazırda mümkün olmalıdır: Bu tablonun içinde birbirleriyle ilişkili, beton kişiler, bu nedenle gibi

+----------+ +----------+ 
| Event | | Notif | 
+----------+ +----------+ 
|   | | Id  | 
| Id  | <- | Evt_id | 
| Type  | <- | Type  | 
| ...  | | ...  | 
+----------+ +----------+ 

Bu benim ne var : Ben LoginNotification_.event ilişkiyi kullanmaya çalıştığınızda

@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>{ 

... 
} 

, ben inat ve herhangi bir Etkinliği getirebilir bu kodu kullanarak, Bildirim, LoginEvent veya NotificationEvent ama yere düşer benim JPA 2.0 metamodel sorgularımda. This issue benzer bir şeyi açıklar. Ben bir kriter sorguda katılmak yapmaya çalıştığınızda

public static volatile SingularAttribute<NotificationEntity, EventEntity> event; 

, bir hata alıyorum:

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); 

Ben LoginNotification_ metamodel yeni SingularAttribute ekleyerek, bu hatanın etrafında alabilirsiniz, ama bu

public abstract class LoginNotification_ extends Notification_ { 

    // Adding this Removes Type mismatch error, but causes run-time error 
    public static volatile SingularAttribute<LoginNotification, LoginEvent> event; 

    ... 
} 

bazı mesajların göre, jenerik ilişkileri, (How to handle JPA annotations for a pointer to a generic interface) çalışmaz ama bir @ManyToOne(optional=false, targetEntity=Event.class) bir kullanarak: yürütme başarısız notasyon, davranması için onları alabiliriz. Ne yazık ki, jenerikler JPA kriter sorgularını kırıyor gibi görünüyor.

Bu aramayı nasıl gerçekleştirebileceğime dair herhangi bir öneriniz var mı? Kodumda LoginNotification.getEvent() kullanabilir, ancak JPA metamodel birleştirmelerimde LoginNotification_.event kullanamıyorum. Bunu başarmak için jenerik kullanmanın alternatifi nedir?

@Pascal Thivent - Bunu cevaplayabilir misiniz? Buna

cevap

8

bir çözüm 'katılmak' fonksiyonunu kullanarak önlemek ve tam çapraz yerine katılmak yapmaktır:

EntityManager em = getEntityManager(); 
CriteriaBuilder cb = em.getCriteriaBuilder(); 
CriteriaQuery<LoginNotification> query = cb.createQuery(LoginNotification.class); 
Root<LoginNotification> notfRoot = query.from(LoginNotification.class); 
Root<LoginEvent> eventRoot = query.from(LoginEvent.class); 
... 
query.where(cb.equals(notfRoot.get(Notification_.event), eventRoot.get(Event_.id)), ...(other criteria)); 
Ben iyi bir sorgu iyileştirici bu kısa çalışması gerektiğini varsayılabilir

ama eğer kimse Bu yaklaşımın verimliliği hakkında herhangi bir kavrayış var, bunu duymaya hevesliyim!

+0

Mükemmel uygular. – logan

0

Genel kodunuzu @logan için denedim.

Ama sonunda basit yolu T izin edilir buldum benim zaten SQL bu şekilde katılır yazmak için kullanılan, Serializable

@Entity 
public class IgsSubject extends BasicObject implements Serializable{ 

    private static final long serialVersionUID = -5387429446192609471L;