Hibernate Books

All times are UTC - 5 hours [ DST ]



Post new topic Reply to topic  [ 9 posts ] 
Author Message
 Post subject: Mapping inheritance : WrongClassException
PostPosted: Sun Jun 25, 2006 9:10 am 
Newbie

Joined: Fri Nov 25, 2005 12:48 pm
Posts: 6
Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp

Hibernate version: 3.2.0-CR1

Hibernate annotations version: 3.1.0-beta10


Name and version of the database you are using : mysql Ver 12.22 Distrib 4.0.24

Hello, I'm trying to map One To many bidirectional associations, I explain :

I have the following class :

Code:
@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 has two bidirectional One To Many associations with technicalSkill and FunctionalSkill.
TechnicalSkill and FunctionalSkill are inherited from the abstract class "Skill".

I use the SINGLE_TABLE strategy :

Code:



@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="TypeSkill", discriminatorType=DiscriminatorType.STRING)
public abstract class Skill 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;
    }

   ...

}





Code:

@Entity
@DiscriminatorValue("FunctionalSkill")
public class FunctionalSkill extends Skill implements IFunctionalSkill
{
   
    private IFunctionalSkillType type = null;
   
    public FunctionalSkill() {}
   

    ..etc

}




Code:
@Entity
@DiscriminatorValue("TechnicalSkill")
public class TechnicalSkill extends Skill implements ITechnicalSkill
{
    private ITechnicalSkillType type = null;
   
    public TechnicalSkill() {}
   
..etc


}




In my web application, when I create a CV (ID is 1 so) , eachtime I add a functionalSkill or a technicalSkill ,the SAVING opération is OK :

In my database I have the table CV and the table SKILL which has a FK "cv_id" . The discriminator column is either "functionalSkill" or "technicalSkill". the cv_id column is not null and has the value 1.

But each time I want to retrieved (fetchmode = eager for the needs of the application) my CV with the ID = 1, the getFunctionalSkill() or the getTechnicalSkill() methods are called.

And ... I have the following exception :


Quote:
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)




Error of mapping of inheritance somewhere??!

Please, I really don't know how to solve my problem since one week !!! :( :(

Any help will be appreciate ![/b]


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 26, 2006 3:41 am 
Expert
Expert

Joined: Sat Oct 25, 2003 8:49 am
Posts: 490
Location: Vrhnika, Slovenia
I think you are missing

Quote:
@ManyToOne(targetEntity=CV.class)
@JoinColumn(name = "cv_id")
public ICV getCv() {
return cv;
}


in Skill class.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 21, 2006 11:53 am 
Regular
Regular

Joined: Tue Sep 28, 2004 5:18 pm
Posts: 55
Location: Switzerland
I'm having the exact same problem.

Two OneToMany collections, each consisting of a different subclass of a mapped superclass.

Hibernate fetches them only by the join column, ignoring the discriminator column. haven't figured out how to fix this.

Have you found a solution?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 21, 2006 12:17 pm 
Regular
Regular

Joined: Tue Sep 28, 2004 5:18 pm
Posts: 55
Location: Switzerland
Solution: Use a hand coded @Where clause to filter by the correct discriminator.

@Where(clause="discriminator_column_name='discriminator_value'")


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 11, 2006 10:44 am 
Beginner
Beginner

Joined: Wed Aug 24, 2005 5:32 am
Posts: 23
Hi,

There is another solution - use can use a unidirectional one-to-many with join table relation. Look here for an example
http://jroller.com/page/eyallupu?entry=getting_a_wrongclassexception_when_mapping

Eyal Lupu


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 01, 2006 12:57 pm 
Newbie

Joined: Fri Jul 15, 2005 6:35 am
Posts: 12
I have the same problem (I'm using the xml mapping, not the annotations)
Is this a bug (or just a bad issue) ?
It will be solved in futere release ?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 18, 2007 8:19 am 
Newbie

Joined: Wed Apr 18, 2007 7:22 am
Posts: 4
The problem with using a custom Where clause is that you have to update it every time you add more subclasses of the class you intend to retrieve.

A better approach is to use Hibernate's extension annotation @org.hibernate.annotations.ForceDiscriminator. The equivalent in Hibernate XML is <discriminator column="..." force="true" />. This causes Hibernate to include a condition on the discriminator column in the Where clause of the generated SQL. The condition will include all subclasses, so you don't have to manually maintain any Where clauses.


Top
 Profile  
 
 Post subject: Re: Mapping inheritance : WrongClassException
PostPosted: Tue May 18, 2010 5:43 am 
Newbie

Joined: Tue May 18, 2010 5:39 am
Posts: 19
The solution of force discriminator (Thanks t_altamimi) works well. But now if this entity is cached in a second level cache, then hibernate does not discriminates uses a discriminator and we have the same problem again ?. Any pointers how to handle this scenario while using second level cache ?

_________________
AG
http://anshuiitk.blogspot.com


Top
 Profile  
 
 Post subject: Re: Mapping inheritance : WrongClassException
PostPosted: Sun Apr 03, 2011 12:20 pm 
Newbie

Joined: Tue May 18, 2010 5:39 am
Posts: 19
A little more explanation of this problem explained http://anshuiitk.blogspot.com/2011/04/h ... ption.html

_________________
AG
http://anshuiitk.blogspot.com


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 9 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.