[hibernate-issues] [Hibernate-JIRA] Created: (HHH-5038) Hibernate's collections pulls out incorrect subclasses when attributes among sub-classes are shared

Ken Egervari (JIRA) noreply at atlassian.com
Thu Mar 25 00:44:31 EDT 2010


Hibernate's collections pulls out incorrect subclasses when attributes among sub-classes are shared
---------------------------------------------------------------------------------------------------

                 Key: HHH-5038
                 URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-5038
             Project: Hibernate Core
          Issue Type: Bug
          Components: core
    Affects Versions: 3.3.2
            Reporter: Ken Egervari
            Priority: Critical


Here's my forum thread.

https://forum.hibernate.org/viewtopic.php?f=1&t=1003481&p=2427675#p2427675

I think there's a probable bug in Hibernate when it comes to one-to-many relationships concerning subclasses that share the same properties.

I am trying to model 3 beans - EducationFacility, Director and Teacher.

Director and Teacher extend from UserAccount

EducationFacility contains 1 director
EducationFacility contains multiple teachers
Director and Teacher have a link back to EducationFacility.

The bug is when Hibernate tries to pull out educationFacility.teachers, it also pulls out the Director as well, because they both have a link to EducationFacility. Hibernate is not properly guarding the "teachers" collection by filtering out Directors. Here is the exception:

{code}
org.springframework.orm.hibernate3.HibernateObjectRetrievalFailureException: Object with id: 9 was not of the specified subclass: jobprep.domain.user.Teacher (loaded object was of wrong class class jobprep.domain.user.Director); nested exception is org.hibernate.WrongClassException: Object with id: 9 was not of the specified subclass: jobprep.domain.user.Teacher (loaded object was of wrong class class jobprep.domain.user.Director)
   at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:666)
   at org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:412)
   at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:411)
   at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
   at org.springframework.orm.hibernate3.HibernateTemplate.delete(HibernateTemplate.java:837)
   at org.springframework.orm.hibernate3.HibernateTemplate.delete(HibernateTemplate.java:833)
{code}

The mapping is as follows:

{code}
    <class name="jobprep.domain.educationfacility.EducationFacility" table="education_facility">
        <id name="id" column="education_facility_id" type="long">
           <generator class="native" />
        </id>

        ....

        <many-to-one name="director" class="jobprep.domain.user.Director"
                     column="director_id" cascade="all" />
        <bag name="teachers" inverse="true" cascade="all-delete-orphan" lazy="true" order-by="username asc">
            <key column="education_facility_id" />
            <one-to-many class="jobprep.domain.user.Teacher" />
        </bag>

        ....

    </class>

    <class name="jobprep.domain.user.UserAccount" table="user_account" abstract="true">
        <id name="id" column="user_account_id" type="long">
            <generator class="native" />
        </id>
        <discriminator column="user_type" type="string"/>

        ....

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

        <subclass name="jobprep.domain.user.Director" discriminator-value="ROLE_DIRECTOR">
            <many-to-one name="educationFacility" class="jobprep.domain.educationfacility.EducationFacility"
                         column="education_facility_id" not-null="false"/>
        </subclass>

        ....
    </class>
{code}

This code actually fixes it:

{code}
        ...

        <subclass name="jobprep.domain.user.Director" discriminator-value="ROLE_DIRECTOR">
            <many-to-one name="educationFacility" class="jobprep.domain.educationfacility.EducationFacility"
                         column="owning_education_facility_id" not-null="false"/>
        </subclass>

        ...
{code}

This works because hibernate's SQL probably pulls out all the UserAccount's that have education_facility_id=?... and since I changed the column name, Hibernate will only pull out Teacher subclasses of UserAccount.

Likewise, if I ever wanted to get all directors (if I ever changed it to be more than one), Hibernate's sql would only fetch the Directors.

But this can't be right... this is so cludgy and bad. I'll work with it for now, but I think there is a problem with Hibernate that needs to be addressed here. When educationFacility.teachers is ever used, it shouldn't pull out Directors in the first place in the sql... but it is.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        


More information about the hibernate-issues mailing list