EDIT :
Je me suis rendu compte en écrivant le message que j'avais laissé mes logs applicatives en INFO lors de mes tentatives de résolution de problème.
En passant en debug, j'ai pu retrouver la coquille qui mettait à mal mon appli. Il s'agissait effectivement d'une bête erreur d'étourderie dans une de mes requêtes JPQL. En fait, l'erreur n'était absolument pas liée à la stratégie de gestion de l'héritage, mais comme elle n'était pas apparue auparavant, j'ai fait le parallèle un peu hâtivement.

Le problème est donc résolu, je laisse la description de mon problème au cas où quelqu'un fait une recherche avec cette pile d'exception. Si un modérateur passe par là, et qu'il estime que le message n'est pas utile pour la postérité, merci d'avance de procéder à sa suppression


Bonjour,

Je rencontre des difficultés à mettre en oeuvre la stratégie "table per subclass" dans mon application.
Je possède une classe mère, plus trois sous-classes qui en héritent. La classe mère porte l'identifiant ainsi que certains champs communs aux 3 autres classes.
En tronquant un peu, mon code Java ressemble donc à ceci :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 
@Entity
@Inheritance(strategy=InheritanceType.JOINED)
public class ClasseMere implements Serializable, Identifiable{
 
	private Long id ;
 
	private String champCommun1 ;
	private String champCommun2 ;
	...
}
 
@Entity
@NamedQueries({plusieurs @NamedQuery})
public class ClasseFille1 extends ClasseMere {
	private String champSpecifique1 ;
	...
}
 
Idem pour les autres classes héritant de la classe mère.
J'ai omis les autres variables, les constructeurs, les getters (annotés avec @Column) et les setters associés.
Avec la stratégie par défaut (SINGLE_TABLE), je ne rencontre aucun problème. En revanche, en utilisant JOINED, une exception est levée lors de la création de l'EntityManagerFactory :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 
Caused by: java.lang.ClassCastException: org.hibernate.hql.ast.tree.IdentNode cannot be cast to org.hibernate.hql.ast.tree.DotNode
	at org.hibernate.hql.ast.tree.AssignmentSpecification.<init>(AssignmentSpecification.java:72)
	at org.hibernate.hql.ast.HqlSqlWalker.evaluateAssignment(HqlSqlWalker.java:1111)
	at org.hibernate.hql.ast.HqlSqlWalker.evaluateAssignment(HqlSqlWalker.java:1105)
	at org.hibernate.hql.antlr.HqlSqlBaseWalker.assignment(HqlSqlBaseWalker.java:1099)
	at org.hibernate.hql.antlr.HqlSqlBaseWalker.setClause(HqlSqlBaseWalker.java:779)
	at org.hibernate.hql.antlr.HqlSqlBaseWalker.updateStatement(HqlSqlBaseWalker.java:374)
	at org.hibernate.hql.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:252)
	at org.hibernate.hql.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:256)
	at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:187)
	at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:138)
	at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:101)
	at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:80)
	at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:124)
	at org.hibernate.impl.SessionFactoryImpl.checkNamedQueries(SessionFactoryImpl.java:549)
	at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:413)
	at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1872)
	at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:906)
	at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:57)
	at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:63)
	at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:47)
	... 4 more
Pour autant, les tables sont bien créées quand j'examine ma base a posteriori. De fait, et compte tenu de la pile d'exception, j'ai l'impression que l'erreur pourrait venir de mes requêtes JPQL (sans en être sûr). Je copie/colle ci-dessous deux de mes requêtes pour référence, au cas où quelqu'un y trouve une erreur. Ceci étant, mes requêtes fonctionnaient parfaitement avant que je cherche à intégrer de l'héritage (et malheureusement, je suis contraint de le faire pour prendre en compte des besoins que j'avais ignorés jusque là).

Merci de votre aide !

Requêtes
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
 
select cf from ClasseFille1 cf 
	left join fetch cf.liensAvecClasseFille2 liensCf2
	left join fetch liensCf2.liensCf3 liensCf3
	where cf.id = :id
 
//(j'ai une deuxième requête similaire, utilisant l'identifiant "naturel", au lieu de la clé artificielle générée par Hibernate)
 
delete ClasseFille1 where identifiantNaturel = :identifiantNaturel
Environnement technique
Java 1.6
Hibernate Core & Hibernate Entity Manager 3.6.8-Final (mais je n'utilise que des classes du package javax.persistence)
Base de données H2 1.3.165 fonctionnant en mode Oracle (la base fonctionne par ailleurs très bien pour les tests unitaires)