Hello,


je suis en train d'essager de mapper des relations One-To-Many bidirectionnelle, je m'explique :

J'ai une classe "CV" :


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
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
 
@Entity
public Class CV
{
 
   private Long id;
   private List<IFunctionalSkill> functionalSkills = new ArrayList<IFunctionalSkill>();
   private List<ITechnicalSkill> technicalSkills = new ArrayList<ITechnicalSkill>();
 
    @Id @GeneratedValue(strategy=GenerationType.AUTO)
   public Long getId() {
      return id;
   }
 
   public void setId(Long id) {
      this.id = id;
   }
 
    /**
     * @return Returns the functionalSkills.
     */
    @OneToMany(mappedBy="cv", targetEntity=FunctionalSkill.class, fetch = FetchType.EAGER)
    @Cascade({ org.hibernate.annotations.CascadeType.ALL, org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
    public List<IFunctionalSkill> getFunctionalSkills()
    {
        return functionalSkills;
    }
 
 
    /**
     * @return Returns the technicalSkills.
     */
    @OneToMany(mappedBy="cv", targetEntity=TechnicalSkill.class, fetch = FetchType.EAGER)
    @Cascade({ org.hibernate.annotations.CascadeType.ALL, org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
    public List<ITechnicalSkill> getTechnicalSkills()
    {
        return technicalSkills;
    }
 
 
}

CV a 2 relations One-To-Many bidirectionelle avec technicalSkill et FunctionalSkill.
TechnicalSkill et FunctionalSkill héritent de la classe abstraite "Skill"

J'utilise la stategie de mappin d'heritage : SINGLE_TABLE per hierarchy (une seule table par hériarchie) :

La classe abstraite Skill est mappée de la manière suivante :


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
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
 
 
@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="TypeSkill", discriminatorType=DiscriminatorType.STRING)
public abstract class Skill extends implements ISkill
{
 
   private Long id;
   private ICV cv;
 
    private Map<String, ISkillDetail> details = new LinkedHashMap<String, ISkillDetail>();
 
    public Skill() {}
 
 
   @Id @GeneratedValue(strategy=GenerationType.AUTO)
   public Long getId() {
      return id;
   }
 
   public void setId(Long id) {
      this.id = id;
   }   
 
   @ManyToOne(targetEntity=CV.class)
    public ICV getCv() {
      return cv;
   }
 
   public void setCv(ICV cv) {
      this.cv = cv;
   }   
 
   // other methods ..etc
 
    /**
     * @return Returns the details.
     */
   @OneToMany(mappedBy="skill", targetEntity=SkillDetail.class, cascade = CascadeType.ALL)
   @MapKey(name="language")   
    public Map<String, ISkillDetail> getDetails()
    {
        return details;
    }
 
    /**
     * @param details The details to set.
     */
    public void setDetails(Map<String, ISkillDetail> details)
    {
        this.details = details;
    }
 
   ...
 
}

Le mapping de la classe "FunctionalSkill" :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 
@Entity
@DiscriminatorValue("FunctionalSkill")
public class FunctionalSkill extends Skill implements IFunctionalSkill
{
 
    private IFunctionalSkillType type = null;
 
    public FunctionalSkill() {}
 
 
    ..etc
 
}
Le mapping de la classe "technicalSkill" :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
 
@Entity
@DiscriminatorValue("TechnicalSkill")
public class TechnicalSkill extends Skill implements ITechnicalSkill
{
    private ITechnicalSkillType type = null;
 
    public TechnicalSkill() {}
 
..etc
 
 
}

Dans mon application web, quand je crée un CV(l'id attribué automatiquement est 1 donc) et que j'ajoute un functionalSkill ou un technicalSkill, l'opération de sauvegarde du CV (saveOrUpdate) fonctionne :

dans ma BD, j'ai une table CV et une table SKILL qui possède une clé étrangère "cv_id". La colonne discriminator d ema table SKILL a soit la valeur "functionalSkill" ou "technicalSkill" selon le cas d'ajout. De plus, La colonne cv_id n'est aps nulle et possède bien la valeur 1 du CV crée.

Mais à chaque fois que je veut récupérer le CV avec l'id 1 , les méthodes getFunctionalSkill() ou getTechnicalSkill() sont appelées (mode fetch = EAGER pour les besoins de l'appli) et j'obtiens l'exceptions :




org.springframework.orm.hibernate3.HibernateObjectRetrievalFailureException: Object with id: 1 was not of the specified subclass: fr.model.hibernate.FunctionalSkill (loaded object was of wrong class); nested exception is org.hibernate.WrongClassException: Object with id: 1 was not of the specified subclass: fr.model.hibernate.FunctionalSkill (loaded object was of wrong class)
org.hibernate.WrongClassException: Object with id: 1 was not of the specified subclass: fr.model.hibernate.FunctionalSkill (loaded object was of wrong class)
at org.hibernate.loader.Loader.instanceAlreadyLoaded(Loader.java:1235)
at org.hibernate.loader.Loader.getRow(Loader.java:1186)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:569)
at org.hibernate.loader.Loader.doQuery(Loader.java:689)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:224)
at org.hibernate.loader.Loader.loadCollection(Loader.java:1919)
at org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:36)
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:520)
at org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:60)
at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1679)
at org.hibernate.collection.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:454)
at org.hibernate.engine.StatefulPersistenceContext.initializeNonLazyCollections(StatefulPersistenceContext.java:755)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:229)
at org.hibernate.loader.Loader.loadEntity(Loader.java:1785)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:48)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:42)
at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:2821)
at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:365)
at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:346)
at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:123)
at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:177)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:87)


Une erreur de mapping d'héritage quelque part??!

Je sais vraiment pas d'où peut venir l'erreur et ça fait uen semaine que je suis dessus !!

Merci d'avance pour votre aide.