In a Spring MVC app using Hibernate and JPA. Hibernate is creating an excessively complex query with 78 joins when only a small number of joins should be necessary. I am using InhertanceType.JOINED
.
To simplify the problem and experiment, I commented out lots of properties in the relevant entities, and I also cut and pasted code from parent classes into subclasses in order to reduce the amount of inheritance. This reduced the number of tables that should be included in joins to 8. But yet when I try an EntityManager.persist()
on one of the entities, hibernate generates joins that should not be included. How can I isolate the problem in my code?
You can view a class diagram of the 8 to 12 classes that should be included in joins by clicking on this link. It is a JPEG file that you can enlarge in your browser by clicking on it. There are only 8 to 12 classes that might be included in joins, but Hibernate is including an additional 12 unrelated tables in the joins, which is completely unnecessary. Why?
Here is a list of the Entities that should not be included in the joins:
PQ
QTY
ANY_
SXCMPQ
IVLPQ
BXITIVLPQ
HXITPQ
PPDPQ
SXCMPPDPQ
IVLPPDPQ
IVXBPPDPQ
IVXBPQ
Here is a list of Entities that should be included in the joins:
Person
LivingEntity
rimEntity
Role
CD
TS
II
EN
Here is the DAO method that is throwing the problem:
@Override
public void saveRIMPerson(Person myperson) throws DataAccessException{
if (myperson.getHppid() == null) {this.em.persist(myperson);}//EXCESSIVE SQL CREATED HERE
else {this.em.merge(myperson);}
}
Here are the joins in the resulting SQL:
Hibernate: select `lots of properties`
from
rim_entity person0_ left outer join CD cd1_ on person0_.classCode_HJID=cd1_.HJID
left outer join TS ivlts2_ on cd1_.VALID_TIME_HXITCE_HJID=ivlts2_.HJID
left outer join II ids3_ on person0_.hppid=ids3_.ids_entity_HJID
left outer join CD cd4_ on person0_.administrativeGenderCode_HJID=cd4_.HJID
left outer join TS ts5_ on person0_.birthTime_HJID=ts5_.HJID
left outer join PQ pq6_ on ts5_.STANDARD_DEVIATION_PPDTS_HJID=pq6_.HJID
left outer join QTY pq6_1_ on pq6_.HJID=pq6_1_.HJID
left outer join ANY_ pq6_2_ on pq6_.HJID=pq6_2_.HJID
left outer join SXCMPQ pq6_3_ on pq6_.HJID=pq6_3_.HJID
left outer join IVLPQ pq6_4_ on pq6_.HJID=pq6_4_.HJID
left outer join BXITIVLPQ pq6_5_ on pq6_.HJID=pq6_5_.HJID
left outer join HXITPQ pq6_6_ on pq6_.HJID=pq6_6_.HJID
left outer join PPDPQ pq6_7_ on pq6_.HJID=pq6_7_.HJID
left outer join SXCMPPDPQ pq6_8_ on pq6_.HJID=pq6_8_.HJID
left outer join IVLPPDPQ pq6_9_ on pq6_.HJID=pq6_9_.HJID
left outer join IVXBPPDPQ pq6_10_ on pq6_.HJID=pq6_10_.HJID
left outer join IVXBPQ pq6_11_ on pq6_.HJID=pq6_11_.HJID
left outer join CD eivlevent7_ on ts5_.EVENT_EIVLPPDTS_HJID=eivlevent7_.HJID
left outer join IVLPPDPQ ivlppdpq8_ on ts5_.OFFSET__EIVLPPDTS_HJID=ivlppdpq8_.HJID
left outer join SXCMPPDPQ ivlppdpq8_1_ on ivlppdpq8_.HJID=ivlppdpq8_1_.HJID
left outer join PPDPQ ivlppdpq8_2_ on ivlppdpq8_.HJID=ivlppdpq8_2_.HJID
left outer join PQ ivlppdpq8_3_ on ivlppdpq8_.HJID=ivlppdpq8_3_.HJID
left outer join QTY ivlppdpq8_4_ on ivlppdpq8_.HJID=ivlppdpq8_4_.HJID
left outer join ANY_ ivlppdpq8_5_ on ivlppdpq8_.HJID=ivlppdpq8_5_.HJID
left outer join CD eivlevent9_ on ts5_.EVENT_EIVLTS_HJID=eivlevent9_.HJID
left outer join IVLPQ ivlpq10_ on ts5_.OFFSET__EIVLTS_HJID=ivlpq10_.HJID
left outer join SXCMPQ ivlpq10_1_ on ivlpq10_.HJID=ivlpq10_1_.HJID
left outer join PQ ivlpq10_2_ on ivlpq10_.HJID=ivlpq10_2_.HJID
left outer join QTY ivlpq10_3_ on ivlpq10_.HJID=ivlpq10_3_.HJID
left outer join ANY_ ivlpq10_4_ on ivlpq10_.HJID=ivlpq10_4_.HJID
left outer join BXITIVLPQ ivlpq10_5_ on ivlpq10_.HJID=ivlpq10_5_.HJID
left outer join TS ppdts11_ on ts5_.CENTER_IVLPPDTS_HJID=ppdts11_.HJID
left outer join TS ivxbppdts12_ on ts5_.HIGH_IVLPPDTS_HJID=ivxbppdts12_.HJID
left outer join TS ivxbppdts13_ on ts5_.LOW_IVLPPDTS_HJID=ivxbppdts13_.HJID
left outer join PPDPQ ppdpq14_ on ts5_.WIDTH_IVLPPDTS_HJID=ppdpq14_.HJID
left outer join PQ ppdpq14_1_ on ppdpq14_.HJID=ppdpq14_1_.HJID
left outer join QTY ppdpq14_2_ on ppdpq14_.HJID=ppdpq14_2_.HJID
left outer join ANY_ ppdpq14_3_ on ppdpq14_.HJID=ppdpq14_3_.HJID
left outer join SXCMPPDPQ ppdpq14_4_ on ppdpq14_.HJID=ppdpq14_4_.HJID
left outer join IVLPPDPQ ppdpq14_5_ on ppdpq14_.HJID=ppdpq14_5_.HJID
left outer join IVXBPPDPQ ppdpq14_6_ on ppdpq14_.HJID=ppdpq14_6_.HJID
left outer join TS ts15_ on ts5_.CENTER_IVLTS_HJID=ts15_.HJID
left outer join TS ivxbts16_ on ts5_.HIGH_IVLTS_HJID=ivxbts16_.HJID
left outer join TS ivxbts17_ on ts5_.LOW_IVLTS_HJID=ivxbts17_.HJID
left outer join PQ pq18_ on ts5_.WIDTH_IVLTS_HJID=pq18_.HJID
left outer join QTY pq18_1_ on pq18_.HJID=pq18_1_.HJID
left outer join ANY_ pq18_2_ on pq18_.HJID=pq18_2_.HJID
left outer join SXCMPQ pq18_3_ on pq18_.HJID=pq18_3_.HJID
left outer join IVLPQ pq18_4_ on pq18_.HJID=pq18_4_.HJID
left outer join BXITIVLPQ pq18_5_ on pq18_.HJID=pq18_5_.HJID
left outer join HXITPQ pq18_6_ on pq18_.HJID=pq18_6_.HJID
left outer join PPDPQ pq18_7_ on pq18_.HJID=pq18_7_.HJID
left outer join SXCMPPDPQ pq18_8_ on pq18_.HJID=pq18_8_.HJID
left outer join IVLPPDPQ pq18_9_ on pq18_.HJID=pq18_9_.HJID
left outer join IVXBPPDPQ pq18_10_ on pq18_.HJID=pq18_10_.HJID
left outer join IVXBPQ pq18_11_ on pq18_.HJID=pq18_11_.HJID
left outer join PPDPQ ppdpq19_ on ts5_.PERIOD_PIVLPPDTS_HJID=ppdpq19_.HJID
left outer join PQ ppdpq19_1_ on ppdpq19_.HJID=ppdpq19_1_.HJID
left outer join QTY ppdpq19_2_ on ppdpq19_.HJID=ppdpq19_2_.HJID
left outer join ANY_ ppdpq19_3_ on ppdpq19_.HJID=ppdpq19_3_.HJID
left outer join SXCMPPDPQ ppdpq19_4_ on ppdpq19_.HJID=ppdpq19_4_.HJID
left outer join IVLPPDPQ ppdpq19_5_ on ppdpq19_.HJID=ppdpq19_5_.HJID
left outer join IVXBPPDPQ ppdpq19_6_ on ppdpq19_.HJID=ppdpq19_6_.HJID
left outer join TS ivlppdts20_ on ts5_.PHASE_PIVLPPDTS_HJID=ivlppdts20_.HJID
left outer join PQ pq21_ on ts5_.PERIOD_PIVLTS_HJID=pq21_.HJID
left outer join QTY pq21_1_ on pq21_.HJID=pq21_1_.HJID
left outer join ANY_ pq21_2_ on pq21_.HJID=pq21_2_.HJID
left outer join SXCMPQ pq21_3_ on pq21_.HJID=pq21_3_.HJID
left outer join IVLPQ pq21_4_ on pq21_.HJID=pq21_4_.HJID
left outer join BXITIVLPQ pq21_5_ on pq21_.HJID=pq21_5_.HJID
left outer join HXITPQ pq21_6_ on pq21_.HJID=pq21_6_.HJID
left outer join PPDPQ pq21_7_ on pq21_.HJID=pq21_7_.HJID
left outer join SXCMPPDPQ pq21_8_ on pq21_.HJID=pq21_8_.HJID
left outer join IVLPPDPQ pq21_9_ on pq21_.HJID=pq21_9_.HJID
left outer join IVXBPPDPQ pq21_10_ on pq21_.HJID=pq21_10_.HJID
left outer join IVXBPQ pq21_11_ on pq21_.HJID=pq21_11_.HJID
left outer join TS ivlts22_ on ts5_.PHASE_PIVLTS_HJID=ivlts22_.HJID
where person0_.hppid=? and person0_.DTYPE='rimPerson'
The code for the Person
entity can be found by clicking on this link. The code for all of the other entities can be found by clicking on this link.
The only thing I can think of is that the underlying MySQL database has many joins on each table, but the database is generated from hbm2ddl using these and other classes as input. Is the problem in my code? Or where else should I look?