Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Map hibernate many-to-one with the foreign key in subclass joined table

Tags:

java

hibernate

I'm mapping some entities using Hibernate 3 for my project and simply explained I've got kind of this:

  • Student entity (tstudent table)
  • UniversityStudent entity (tuniversitystudent table)
  • University entity (tuniversity table)

UniversityStudent extends from Student and has its own attributes, like the university itself, which is a foreign key into the tuniversitystudent table. It is also mapped like a subclass into the Student class, using a discriminator field:

<class name="mycompany.Student" table="tstudent" discriminator-value="BASIC">
    <id name="id" column="id" type="integer">
        <generator class="native" />
    </id>
    <discriminator column="type" />
    <property name="name" column="name" />
    <property name="surname" column="surname" />
    <property name="phoneNumber" column="phone_number" />
    <subclass discriminator-value="UNIVERSITY"
            name="mycompany.UniversityStudent">
        <join table="tuniversitystudent">
            <key column="id_student" />
            <many-to-one name="university" class="mycompany.University">
                <column name="id_university" />
            </many-to-one>
        </join>
    </subclass>
</class>

Well, now I want to have a Set collection with the UniversityStudent entities for each University. So I map it like that:

<class name="mycompany.University" table="tuniversity">
    <id name="id" column="id" type="integer">
        <generator class="native" />
    </id>
    <property name="name" column="name" />
    <set name="universityStudents" table="tuniversitystudent">
        <key>
            <column name="id_university" />
        </key>
        <one-to-many class="mycompany.UniversityStudent" />
    </set>
</class>

My problem comes when I want to load a University object, Hibernate complains that id_university doesn't exist in tstudent table. I checked the generated SQL query and it really tries to load it from tstudent.

Unknown column 'student0_.id_university' in 'field list'

It seems that it's recognizing that it is a subclass of the basic Student and tries to join the collection using a field in the parent table, but however the field is actually in the child table, because only university students can have a University assigned.

I tried another workaround which seems to work but it's not valid for me, that's mapping the UniversityStudent as a joined-subclass instead of a subclass with a join inside:

<joined-subclass name="mycompany.UniversityStudent" table="tuniversitystudent">
    <key column="id_student" />
    <many-to-one name="university" class="mycompany.University">
        <column name="id_university" />
    </many-to-one>
</joined-subclass>

However, I'm interested in keeping it as a subclass with a discriminator value. Any idea?

like image 802
Xtreme Biker Avatar asked Oct 21 '22 04:10

Xtreme Biker


1 Answers

I checked out some resources and finally got into this bug: https://hibernate.atlassian.net/browse/HHH-1015, which looks absolutely compatible with your case. Checkout this old question as well, again very similar to your case.
I firstly read the definition of table per sublass given by Hibernate (I know, it is for version 3.3 but I couldn't find the same source for Hibernate 4): joined-subclass seems (to me) to be a custom implementation of subclass using a discriminator provided by Hibernate and that is a good reason to stay away from its usage. However, from what I know, the mappings table per sublass and table per subclass using a discriminator should be equivalent, that's why I believe the bug I pointed you out is really still open.

If you have time and will, you can try to use another JPA provider and check if you still run in the same issue. JPA 2.0 specifications is a thing, provider implementation is another! I recently run into another bug (related to @IdClass) which forced me to try EclipseLink and the configuration which was not working with Hibernate was right with Eclipse Link

like image 131
ThanksForAllTheFish Avatar answered Oct 26 '22 22:10

ThanksForAllTheFish