2010-08-22 5 views
4

J'ai une hiérarchie de classes comme ceci:JPA héritage entitymanager.find produit ClassCastException

@Entity 
@Table (name="call_distribution_policies") 
@Inheritance (strategy=InheritanceType.JOINED) 
public class CallDistributionPolicy implements Serializable, Cloneable{ 
    ---------------- 
} 

@Entity 
@Table(name="skill_based_call_distribution_policies") 
public class SkillBasedCallDistributionPolicy extends CallDistributionPolicy { 

    -------------- 
} 

public class CallDistributionPolicyDAOJPAImpl extends 
    AbstractJPADAOImpl<CallDistributionPolicy> implements 
    CallDistributionPolicyDAO { 
} 

    public CallDistributionPolicy get(long id) { 
    try { 
     Query query = entityManager 
       .createQuery("from CallDistributionPolicy where id = :id"); 

     query.setParameter("id", id); 

     List<CallDistributionPolicy> resultList = query.getResultList(); 

     if (!CollectionUtils.isEmpty(resultList)) { 
      return resultList.get(0); 
     } 

     return null; 
    } catch (EntityNotFoundException e) { 
     return null; 
    } 
} 
} 

Quand je fais ceci: log.debug ("chargé:" + callDistributionPolicyDao.get (10) .toString())

il imprime la toString() du SkillsBasedCallDistributionPolicy

Mais lorsque je tente de le jeter comme ceci:

SkillsBasedCallDistributionPolicy scdp = (SkillsBasedCallDistributionPolicy) callDistributionPolicyDao.get(10) 

Je reçois une exception de conversion de classe.

com.vantage.callcenter.core.entity.acd.CallDistributionPolicy$$EnhancerByCGLIB$$334f3d1b cannot be cast to com.vantage.callcenter.core.entity.acd.SkillBasedCallDistributionPolicy 

La vérification de l'instance échoue aussi!

Lorsque j'inspecte l'objet dans Eclipse, je vois le proxy CGLIB, mais si je comprends bien, le proxy CGLIB devrait étendre la classe SkillsBasedCallDistributionPolicy? Dans la propriété CGLIB $ CALLBACK_0, je peux voir la classe d'entité est "CallDistributionPolicy" mais la cible est "SkillsBasedCallDistributionPolicy".

Quel devrait être le processus approprié de chargement de la sous-classe? Je peux voir hibernate générer tout le droit SQL et le chargement de la sous-classe appropriée, mais comment puis-je vérifier l'instanceof et le jeter dans une sous-classe? J'utilise Hibernate 3.2.1, Spring 2.5.5, cglib2.1_3. Aucune suggestion?

+0

Qu'est-ce 'AbstractJPADAOImpl'? Comment le DAO est-il branché au printemps? – skaffman

Répondre

2

Je sais que cela a été un problème dans Hibernate pendant longtemps, voir par exemple:

Et par problème, je signifie bug, instanceof et le moulage devrait juste fonctionner.

Mais je ne pouvais pas reproduire votre problème avec Hibernate 3.3.0.SP1. Les deux instanceof et la distribution aux sous-classes d'une hiérarchie en utilisant une stratégie jointe vient de fonctionner. Testé avec:

<dependency> 
     <groupId>org.hibernate</groupId> 
     <artifactId>hibernate-cglib-repack</artifactId> 
     <version>2.1_3</version> 
    </dependency> 

et

<dependency> 
     <groupId>javassist</groupId> 
     <artifactId>javassist</artifactId> 
     <version>3.8.0.GA</version> 
    </dependency> 

Je suis sûr qu'il y avait un problème Jira pour cela, mais n'a pas pu le trouver.


Le problème (bug) est cohérente dans ma demande. Pouvez-vous poster votre pom.xml de travail ici afin que je puisse voir exactement quelles dépendances hibernate utilisez-vous?

Ci-dessous les dépendances: j'ai utilisé

<project> 
    ... 
    <dependencyManagement> 
    <dependencies> 
     <dependency> 
     <groupId>org.slf4j</groupId> 
     <artifactId>slf4j-api</artifactId> 
     <version>1.5.10</version> 
     </dependency> 
    </dependencies> 
    </dependencyManagement> 
    ... 
    <dependencies> 
    <dependency> 
     <groupId>org.hibernate</groupId> 
     <artifactId>hibernate-entitymanager</artifactId> 
     <version>3.4.0.GA</version> 
     <exclusions> 
     <exclusion> 
      <groupId>javassist</groupId> 
      <artifactId>javassist</artifactId> 
     </exclusion> 
     </exclusions> 
    </dependency> 
    <dependency> 
     <groupId>org.hibernate</groupId> 
     <artifactId>hibernate-cglib-repack</artifactId> 
     <version>2.1_3</version> 
    </dependency> 
    ... 
    </dependencies> 
</project> 

Voici l'arbre de dépendance:

 
[INFO] +- org.hibernate:hibernate-entitymanager:jar:3.4.0.GA:compile 
[INFO] | +- org.hibernate:ejb3-persistence:jar:1.0.2.GA:compile 
[INFO] | +- org.hibernate:hibernate-commons-annotations:jar:3.1.0.GA:compile 
[INFO] | +- org.hibernate:hibernate-annotations:jar:3.4.0.GA:compile 
[INFO] | +- org.hibernate:hibernate-core:jar:3.3.0.SP1:compile 
[INFO] | | +- antlr:antlr:jar:2.7.6:compile 
[INFO] | | \- commons-collections:commons-collections:jar:3.1:compile 
[INFO] | +- org.slf4j:slf4j-api:jar:1.5.10:compile 
[INFO] | +- dom4j:dom4j:jar:1.6.1:compile 
[INFO] | | \- xml-apis:xml-apis:jar:1.0.b2:compile 
[INFO] | \- javax.transaction:jta:jar:1.1:compile 
... 
[INFO] \- org.hibernate:hibernate-cglib-repack:jar:2.1_3:compile 
+0

Bonjour Pascal, Merci pour votre réponse. Le problème (bug) est cohérent dans mon application. Pouvez-vous poster votre pom.xml de travail ici afin que je puisse voir exactement quelles dépendances hibernate utilisez-vous? – Sajid

+0

@Sajid Sure. Voir ma mise à jour –

+0

Merci, je vais mettre à jour mon pom et voir si cela fait une différence. – Sajid