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" :
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
14 @Entity @DiscriminatorValue("FunctionalSkill") public class FunctionalSkill extends Skill implements IFunctionalSkill { private IFunctionalSkillType type = null; public FunctionalSkill() {} ..etc }
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 :
Une erreur de mapping d'héritage quelque part??!
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)
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.
Partager