Hibernate many-to-one map with foreign key in subclass

I map some objects using Hibernate 3 for my project and just explain that I have a view of this:

  • Student entity (tstudent table)
  • UniversityStudent entity (diversity table)
  • University entity (diversity table)

UniversityStudent extends from Student and has its own attributes, such as the university itself, which is the foreign key in the tuniversitystudent table. It also appears as a subclass of the Student class using the 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 UniversityStudent objects for each University . Therefore, I find it as follows:

 <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 occurs when I want to load a University object, Hibernate complains that id_university does not exist in the tstudent table. I checked the generated SQL query and it is really trying to load it from tstudent.

Unknown column 'student0_.id_university' in 'list of fields'

It seems that he recognizes that he is a subclass of the main Student and tries to join the collection using the field in the parent table, but, however, the field is indeed in the child table, since only university students can have the university appointed.

I tried another workaround that seems to work, but it is not valid for me that displaying UniversityStudent as joined-subclass instead of subclass with 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 am interested in saving it as a subclass with a discriminator value. Any idea?

+4
source share
2 answers

I checked some resources and finally got into this error: 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.
First I read the table per sublass definition given by Hibernate (I know this is for version 3.3, but I could not find the same source for Hibernate 4): joined-subclass seems to me (a) in order to be a custom implementation of subclass using a discriminator provided by Hibernate, and this is a good reason to stay away from its use. However, from what I know, the comparisons of the table for the submarine and the table for each subclass using the discriminator should be equivalent, so I believe that the error I pointed out to you is really still open.

If you have the time and desire, you can try to use another JPA provider and check if you are all working in the same problem. JPA 2.0 specifications are a thing, vendor implementation is another! I recently ran into another bug (related to @IdClass ) that made me try EclipseLink and the configuration that didn't work with Hibernate was right with Eclipse Link

+2
source

It seems you can use Custom SQL (or HQL) to load . I have not tried this myself, but it seems that hmm, at least in extreme cases, it provides a decent solution.

Define the request in your HBM:

 <sql-query name="universityStudents"> <load-collection alias="unistu" role="University.universityStudents"/> SELECT unistu.*, student.* FROM tuniversitystudent unistu JOIN tstudent student ON unistu.id_student = student.id WHERE unistu.id_university = :id </sql-query> 

And then use it inside the University :

 <set name="universityStudents" inverse="true"> <key/> <one-to-many class="mycompany.UniversityStudent"/> <loader query-ref="universityStudents"/> </set> 
+1
source

Source: https://habr.com/ru/post/1494477/


All Articles