These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 
Author Message
 Post subject: Please help with this Subclass problem
PostPosted: Wed May 13, 2009 12:16 am 
Regular
Regular

Joined: Tue May 12, 2009 6:08 am
Posts: 92
Hi everyone.

I'm trying to delete a row out of a table that has 3 sub-classes. It's just mapped to 1 table to keep it simple. However, I'm getting a weird exception:
Code:
org.hibernate.WrongClassException: Object with id: 1 was not of the specified subclass: jobprep.domain.Teacher (loaded object was of wrong class class jobprep.domain.Admin)


The code is so trivial too...
Code:
   public void delete( long id ) {
      this.sessionFactory.getCurrentSession().delete( find( id ) );
   }

   public User find( long id ) {
      return ( User ) this.sessionFactory.getCurrentSession().get( User.class, id );
   }


Since I'm not even using Admin or Teacher subclasses... I don't get why this doesn't work. Here is my mapping:

Code:
    <class name="jobprep.domain.User" table="user_account" abstract="true">
        <id name="id" column="user_account_id" type="long">
            <generator class="sequence">
                <param name="sequence">user_account_id_sequence</param>
            </generator>
        </id>
        <discriminator column="user_type" type="string"/>
        <property name="firstName" column="first_name"/>
        <property name="lastName" column="last_name"/>
        <property name="emailAddress" column="email_address"/>
        <property name="username" column="username"/>
        <property name="password" column="password"/>

        <subclass name="jobprep.domain.Student" discriminator-value="STUDENT">
            <bag name="activeModules" inverse="true" cascade="all-delete-orphan" lazy="true">
                <key column="user_account_id" not-null="true"/>
                <one-to-many class="jobprep.domain.ActiveModule"/>
            </bag>
        </subclass>

        <subclass name="jobprep.domain.Teacher" discriminator-value="TEACHER">
            <many-to-one name="educationFacility" class="jobprep.domain.EducationFacility"
                         column="education_facility_id" not-null="true" />
            <bag name="students" inverse="true" cascade="all-delete-orphan" lazy="true">
                <key column="user_account_id" not-null="true"/>
                <one-to-many class="jobprep.domain.Student"/>
            </bag>
        </subclass>

        <subclass name="jobprep.domain.Admin" discriminator-value="ADMIN">
            <bag name="modules" inverse="true" cascade="all-delete-orphan" lazy="true">
                <key column="user_account_id" not-null="true"/>
                <one-to-many class="jobprep.domain.Module"/>
            </bag>
            <bag name="educationFacilities" inverse="true" cascade="all-delete-orphan" lazy="true">
                <key column="user_account_id" not-null="true"/>
                <one-to-many class="jobprep.domain.EducationFacility"/>
            </bag>
        </subclass>
    </class>


It's interesting... when the project was simpler, this mapping and the deletes worked fine. Now that the database has grown... this problem just magically started showing up. Can anyone help please?

Here are the rest of the mappings... in case the problem is here:
Code:
    <class name="jobprep.domain.EducationFacility" table="education_facility">
        <id name="id" column="education_facility_id" type="long">
            <generator class="sequence">
                <param name="sequence">education_facility_id_sequence</param>
            </generator>
        </id>
        <property name="name" column="name"/>
        <bag name="teachers" inverse="true" cascade="all-delete-orphan" lazy="true">
            <key column="education_facility_id" not-null="true"/>
            <one-to-many class="jobprep.domain.Teacher"/>
        </bag>
        <bag name="allowedModules" table="modules_to_education_facilities" inverse="true" cascade="all-delete-orphan" lazy="true">
            <key column="education_facility_id" not-null="true"/>
            <many-to-many class="jobprep.domain.Module" column="module_id"/>
        </bag>
        <many-to-one name="admin" class="jobprep.domain.Admin" column="user_account_id" not-null="true" />
    </class>

    <class name="jobprep.domain.Hint" table="hint">
        <id name="id" column="hint_id" type="long">
            <generator class="sequence">
                <param name="sequence">hint_id_sequence</param>
            </generator>
        </id>
        <many-to-one name="question" class="jobprep.domain.Question" column="question_id"  not-null="true" />
        <property name="text" column="text"/>
        <property name="attemptsNeeded" column="attempts_needed"/>
    </class>

    <class name="jobprep.domain.Answer" table="answer" abstract="true">
        <id name="id" column="answer_id" type="long">
            <generator class="sequence">
                <param name="sequence">answer_id_sequence</param>
            </generator>
        </id>
       <discriminator column="type" type="string"/>
       <many-to-one name="question" class="jobprep.domain.Question" column="question_id" not-null="true" />
       <property name="originality" column="originality" />
       <property name="text" column="text" />

       <subclass name="jobprep.domain.TextAnswer" discriminator-value="TEXT">
          <property name="looseMatching" column="loose_matching"/>
       </subclass>

       <subclass name="jobprep.domain.RegexAnswer" discriminator-value="REGEX">
          <property name="regularExpression" column="regular_expression"/>
       </subclass>
    </class>

    <class name="jobprep.domain.Question" table="question">
        <id name="id" column="question_id" type="long">
            <generator class="sequence">
                <param name="sequence">question_id_sequence</param>
            </generator>
        </id>
        <property name="text" column="text"/>
       <many-to-one name="task" class="jobprep.domain.Task" column="task_id" not-null="true" />
       <bag name="activeQuestions" inverse="true" cascade="all-delete-orphan" lazy="true">
           <key column="question_id" not-null="true"/>
           <one-to-many class="jobprep.domain.ActiveQuestion"/>
       </bag>
       <bag name="answers" inverse="true" cascade="all-delete-orphan" lazy="false">
           <key column="question_id" not-null="true"/>
           <one-to-many class="jobprep.domain.Answer" />
       </bag>
        <bag name="hints" inverse="true" cascade="all-delete-orphan" lazy="false">
            <key column="question_id" not-null="true"/>
            <one-to-many class="jobprep.domain.Hint"/>
        </bag>
        <property name="points" column="points"/>
    </class>

    <class name="jobprep.domain.ActiveQuestion" table="active_question">
        <id name="id" column="active_question_id" type="long">
            <generator class="sequence">
                <param name="sequence">active_question_id_sequence</param>
            </generator>
        </id>
        <property name="isAnswered" column="is_answered"/>
        <property name="failedAttempts" column="failed_attempts"/>
        <many-to-one name="question" class="jobprep.domain.Question" column="question_id" not-null="true" />
    </class>

    <class name="jobprep.domain.Task" table="task">
        <id name="id" column="task_id" type="long">
            <generator class="sequence">
                <param name="sequence">task_id_sequence</param>
            </generator>
        </id>
        <property name="name" column="name"/>
       <many-to-one name="module" class="jobprep.domain.Module" column="module_id" not-null="true" />
        <set name="questions" inverse="true" cascade="all-delete-orphan" lazy="false" fetch="join">
            <key column="task_id" not-null="true"/>
            <one-to-many class="jobprep.domain.Question"/>
        </set>
    </class>

    <class name="jobprep.domain.Module" table="module">
        <id name="id" column="module_id" type="long">
            <generator class="sequence">
                <param name="sequence">module_id_sequence</param>
            </generator>
        </id>
        <property name="name" column="name"/>
        <many-to-one name="admin" class="jobprep.domain.Admin" column="user_account_id" not-null="true" />
        <bag name="tasks" inverse="true" cascade="all-delete-orphan" lazy="true">
            <key column="module_id" not-null="true"/>
            <one-to-many class="jobprep.domain.Task"/>
        </bag>
    </class>

    <class name="jobprep.domain.ActiveModule" table="active_module">
        <id name="id" column="active_module_id" type="long">
            <generator class="sequence">
                <param name="sequence">active_module_id_sequence</param>
            </generator>
        </id>
        <property name="isComplete" column="is_complete"/>
        <many-to-one name="module" class="jobprep.domain.Module" column="module_id" not-null="true" />
        <bag name="students" inverse="true" cascade="all-delete-orphan" lazy="true">
            <key column="active_module_id" not-null="true"/>
            <one-to-many class="jobprep.domain.Student"/>
        </bag>
    </class>


Last edited by mystic on Wed May 13, 2009 3:32 am, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: Please help with this Subclass problem
PostPosted: Wed May 13, 2009 1:14 am 
Regular
Regular

Joined: Tue May 12, 2009 6:08 am
Posts: 92
Very interesting. I added not-null="true" to my many-to-one associations, and it fixed the problem. No worries ;)


Top
 Profile  
 
 Post subject: Re: Please help with this Subclass problem
PostPosted: Wed May 13, 2009 3:31 am 
Regular
Regular

Joined: Tue May 12, 2009 6:08 am
Posts: 92
Actually... this problem is not fixed :( It's happening again. I'm at a total loss.

I have 3 rows in the database. Id 1 = an admin. Id 2 = a student. Id 3 = a teacher.

The problem is that it's loading the correct one, but then hibernate expects a different one (the student type for example). This is only happening on deletes.

It's interesting. If I change to "cascade="none"....
Code:
        <subclass name="jobprep.domain.Teacher" discriminator-value="TEACHER">
            <many-to-one name="educationFacility" class="jobprep.domain.EducationFacility"
                         column="education_facility_id" not-null="true" />
            <bag name="students" inverse="true" cascade="none" lazy="true">
                <key column="user_account_id" not-null="true"/>
                <one-to-many class="jobprep.domain.Student"/>
            </bag>
        </subclass>


... The problem goes away. I'm guessing it doesn't like the recursive definition here. Can I make the type matching more strict to enable cascading?


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 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.