2012-02-02 4 views
0

Problème avec l'héritage dans les entités JPA avec la stratégie SINGLE_TABLE. Dans getters @Discriminator réduire la gamme de l'héritage.Héritage avec stratégie SINGLE_TABLE dans JPA et @Discriminator dans getter

J'ai la structure suivante:

@Entity 
@Inheritance(strategy=InheritanceType.SINGLE_TABLE) 
@DiscriminatorColumn(name="type") 
@DiscriminatorValue("A") 
class A { 
... 
} 

@Entity 
@DiscriminatorValue("B") 
class B extends A { 
... 
} 

@Entity 
@DiscriminatorValue("C") 
class C extends B { 
... 
} 

@Entity 
class Something{ 
@ManyToMany // blah blah 
private List<B> listB; // getters and setters 
} 

problème suit. J'ai l'objet de la classe C (en supposant que l'héritage C est aussi B). Quand je fais:

Something s = Something.findById(11); // Here is listB with elements of type C and B 
List<B> listB = s.getListB(); 

Je n'extraient que des objets de la classe B, C. Mais aucun C Prolonge B, il devrait également être sur la liste. Getter construit une telle requête:

SELECT t1.id, t1.type, t1.sys_modified_date, t1.sys_created_date, t1.name, t1.shortName 
FROM something_b t0 INNER JOIN A t1 ON t0.listB = t1.id 
WHERE t0.news = ? AND t1.type = ? 
[params=(long) 205, (String) B] 

Le problème est que ce getter (Something.getListB) réduire cette liste que la classe B (par discriminateur B). Cela entraîne que la classe d'objet C ne figure pas dans la liste. Il est provoqué par @Discriminator en indiquant le type strict "t1.type = B". Il ne permet pas d'y mettre un ensemble/liste comme "t1.type IN (B, C)".

Les requêtes personnalisées JPQL sont des constructions de manière différente:

SELECT t1.id, t1.type, t1.sys_modified_date, t1.sys_created_date, t1.name, t1.shortName 
FROM something_b t0 INNER JOIN A t1 ON t0.listB = t1.id 
WHERE t0.news = ? AND t1.type IN (?, ?) 
[params=(long) 205, (String) B, (String) C] 

et ils fonctionnent comme ils le devraient. Mais qu'en est-il de getter?

Il est intéressant que quand je change de classe Quelque chose de la classe B à la classe A (base pour tous): @Entity Quelque chose de classe {// @ManyToMany bla bla Liste privée listeA; // getters et setters }

cela résout le problème. Dans le getter dans la requête:

SELECT t1.id, t1.type, t1.sys_modified_date, t1.sys_created_date, t1.name, t1.shortName 
FROM something_b t0 INNER JOIN A t1 ON t0.listB = t1.id 
WHERE t0.news = ? 
[params=(long) 205] 

disparaît "AND t1.type =?". Cela fonctionne mais cela perturbe le mappage des "objets du monde réel" aux "entités ORM". Cette solution change, aggrave cette abstraction. Ce n'est pas une solution élégante.

Question:

Comment puis-je résoudre ce problème? Puis-je utiliser une requête JPQL personnalisée dans getter?

Comment forcer le getter à extraire des objets B et C?

Avez-vous une autre proposition au lieu de changer Liste à Liste ???

Répondre

0

Quel fournisseur JPA utilisez-vous? Ça a l'air d'un bug. Cela devrait fonctionner avec EclipseLink.

+0

Nous utilisons Open JPA dans la version 2.1.0. Avez-vous de l'expérience avec d'autres fournisseurs JPA en ce qui concerne le bug? – Mariomario85

Questions connexes