Hi, I'm getting the following exception, where Hibernate is trying to load a subclass of one type, but the object being returned is another type. The type that Hibernate is expecting is actually wrong. ID 2 really is supposed to be OpenEndedQuestion. So the type it's loading is fine... I dunno why Hibernate is complaining for.
Here is the exception:
Code:
org.springframework.orm.hibernate3.HibernateObjectRetrievalFailureException: Object with id: 2 was not of the specified subclass: jobprep.domain.finite.FiniteQuestion (loaded object was of wrong class class jobprep.domain.openended.OpenEndedQuestion); nested exception is org.hibernate.WrongClassException: Object with id: 2 was not of the specified subclass: jobprep.domain.finite.FiniteQuestion (loaded object was of wrong class class jobprep.domain.openended.OpenEndedQuestion)
   at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:663)
   at org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:412)
   at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:424)
   at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
   at org.springframework.orm.hibernate3.HibernateTemplate.get(HibernateTemplate.java:525)
   at org.springframework.orm.hibernate3.HibernateTemplate.get(HibernateTemplate.java:519)
   at jobprep.dao.ActiveModuleDaoImpl.find(ActiveModuleDaoImpl.java:34)
   at jobprep.service.StudentServiceTests.assertActiveModuleContainsAmountOfActiveQuestions(StudentServiceTests.java:173)
   at jobprep.service.StudentServiceTests.testEntireModuleToCompleteWithUser(StudentServiceTests.java:140)
   at jobprep.service.StudentServiceTests.testEntireModuleToComplete(StudentServiceTests.java:120)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at org.springframework.test.context.junit4.SpringTestMethod.invoke(SpringTestMethod.java:160)
   at org.springframework.test.context.junit4.SpringMethodRoadie.runTestMethod(SpringMethodRoadie.java:233)
   at org.springframework.test.context.junit4.SpringMethodRoadie$RunBeforesThenTestThenAfters.run(SpringMethodRoadie.java:333)
   at org.springframework.test.context.junit4.SpringMethodRoadie.runWithRepetitions(SpringMethodRoadie.java:217)
   at org.springframework.test.context.junit4.SpringMethodRoadie.runTest(SpringMethodRoadie.java:197)
   at org.springframework.test.context.junit4.SpringMethodRoadie.run(SpringMethodRoadie.java:143)
   at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.invokeTestMethod(SpringJUnit4ClassRunner.java:160)
   at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
   at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
   at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
   at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
   at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
   at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:97)
   at com.intellij.rt.junit4.Junit4TestMethodAdapter.run(Junit4TestMethodAdapter.java:62)
   at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:40)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at com.intellij.rt.execution.application.AppMain.main(AppMain.java:90)
Here are two parts of the mapping where this could be the issue:
Code:
    <class name="jobprep.domain.Question" table="question" abstract="true">
        <id name="id" column="question_id" type="long">
            <generator class="sequence">
                <param name="sequence">question_id_sequence</param>
            </generator>
        </id>
       <discriminator column="type" type="string"/>
       <many-to-one name="task" class="jobprep.domain.Task" column="task_id" not-null="true" />
       <property name="text" column="text"/>
       <property name="ordering" column="ordering"/>
       <property name="successMessage" column="success_message"/>
       <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>
       <subclass name="jobprep.domain.finite.FiniteQuestion" discriminator-value="FINITE">
          <bag name="expectedAnswers" inverse="true" cascade="all-delete-orphan" order-by="text asc" lazy="false">
              <key column="question_id" not-null="true"/>
              <one-to-many class="jobprep.domain.finite.QuestionKeyword" />
          </bag>
           <bag name="hints" inverse="true" cascade="all-delete-orphan" order-by="attempts_needed asc" lazy="false">
               <key column="question_id" not-null="true"/>
               <one-to-many class="jobprep.domain.Hint"/>
           </bag>
          <property name="engineType" column="engine_type"/>
          <property name="minimumNumberOfKeywords" column="minimum_number_of_keywords"/>
       </subclass>
       <subclass name="jobprep.domain.openended.OpenEndedQuestion" discriminator-value="OPEN-ENDED">
          <bag name="keywords" inverse="true" cascade="all-delete-orphan" order-by="text asc" lazy="false">
              <key column="question_id" not-null="true"/>
              <one-to-many class="jobprep.domain.finite.QuestionKeyword" />
          </bag>
          <property name="minimumNumberOfWords" column="minimum_number_of_words"/>
          <property name="minimumNumberOfWordsForFirstAttempt" column="minimum_number_of_words_for_first_attempt"/>
          <property name="minimumNumberOfSentences" column="minimum_number_of_sentences"/>
          <property name="minimumNumberOfKeywords" column="minimum_number_of_keywords"/>
       </subclass>
       <subclass name="jobprep.domain.category.CategoryBasedQuestion" discriminator-value="CATEGORY-BASED">
         <bag name="categories" inverse="true" cascade="all-delete-orphan" order-by="name asc" lazy="false">
              <key column="question_id" not-null="true"/>
              <one-to-many class="jobprep.domain.category.Category"/>
          </bag>
       </subclass>
    </class>
and this one:
Code:
   <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>
      <many-to-one name="activeTask" class="jobprep.domain.ActiveTask" column="active_task_id"
                   not-null="true" cascade="all" />
      <component name="results" class="jobprep.domain.QuestionResults">
         <bag name="results" inverse="true" cascade="all-delete-orphan" lazy="false"
            order-by="creation_date asc">
             <key column="active_question_id" not-null="true"/>
             <one-to-many class="jobprep.domain.QuestionResult"/>
         </bag>
      </component>
      <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" cascade="none" />
      <property name="creationDate" column="creation_date"/>
   </class>
   <class name="jobprep.domain.QuestionResult" table="question_result" abstract="true">
       <id name="id" column="question_result_id" type="long">
           <generator class="sequence">
               <param name="sequence">question_result_id_sequence</param>
           </generator>
       </id>
      <discriminator column="type" type="string"/>
      <many-to-one name="activeQuestion" class="jobprep.domain.ActiveQuestion" column="active_question_id"
                   not-null="true" cascade="none" />
      <property name="creationDate" column="creation_date"/>
      <subclass name="jobprep.domain.finite.FiniteResult" discriminator-value="FINITE">
         <many-to-one name="question" class="jobprep.domain.finite.FiniteQuestion" column="question_id"
                      not-null="true" cascade="all" />
         <property name="suppliedAnswer" column="supplied_answer"/>
         <bag name="answers" table="question_result_to_answer" inverse="true"
              cascade="all" order-by="text asc" lazy="false">
             <key column="question_result_id" not-null="true"/>
             <many-to-many class="jobprep.domain.finite.QuestionKeyword" column="answer_id" />
         </bag>
      </subclass>
      <subclass name="jobprep.domain.openended.OpenEndedResult" discriminator-value="OPEN-ENDED">
         <many-to-one name="question" class="jobprep.domain.openended.OpenEndedQuestion" column="question_id"
                      not-null="true" cascade="all" />
         <property name="suppliedAnswer" column="supplied_answer"/>
      </subclass>
      <subclass name="jobprep.domain.category.CategoryBasedResult" discriminator-value="CATEGORY-BASED">
         <many-to-one name="question" class="jobprep.domain.category.CategoryBasedQuestion" column="question_id"
                      not-null="true" cascade="all" />
         <bag name="answers" table="question_result_to_category_answer" inverse="true"
              cascade="all" order-by="text asc" lazy="false">
             <key column="question_result_id" not-null="true"/>
             <many-to-many class="jobprep.domain.category.CategoryAnswer" column="category_answer_id" />
         </bag>
      </subclass>
   </class>
Lastly, here are the database rows:
Code:
   <question question_id="1" text="What is Sisko's first name?" task_id="1"
             ordering="0" success_message="Correct!" type="FINITE" engine_type="SINGLE"
             minimum_number_of_keywords="1" />
   <question question_id="2" text="Why do you like Star Trek?" task_id="1"
             ordering="1" success_message="You are a geek!" type="OPEN-ENDED"
             minimum_number_of_keywords="0" minimum_number_of_words="4"
             minimum_number_of_sentences="1" minimum_number_of_words_for_first_attempt="2"/>
   <question question_id="3" text="Match the Star Trek items" task_id="1"
             ordering="2" success_message="You are a trekkie!" type="CATEGORY-BASED"/>
   <question question_id="4" text="Am I done yet?" task_id="2"
             ordering="0" success_message="" type="OPEN-ENDED"
             minimum_number_of_keywords="0" minimum_number_of_words="4"
             minimum_number_of_sentences="1" minimum_number_of_words_for_first_attempt="2"/>
Clearly, id 2 is of type "OPEN-ENDED", so it doesn't make much sense why hibernate wants "FINITE" :( Hibernate is messed up.
This error happens when loading a totally different object... but when it's loading the object graph, something went wrong I guess? I dunno. I don't understand why this is failing.
Help?