title: Hibernate generating excessive number of joins in select query
body: <p>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 <code>InhertanceType.JOINED</code>.</p>
  
  <p>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 <code>EntityManager.persist()</code> on one of the entities, hibernate generates joins that should not be included.  How can I isolate the problem in my code?  </p>
  
  <p>You can view a class diagram of the 8 to 12 classes that should be included in joins <a href="https://jumpshare.com/v/3ZSBed9a26D1gst6MVEg?b=ZBRu2GqYPvW4jqz3rM9a" rel="nofollow noreferrer">by clicking on this link</a>.  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?</p>
  
  <p>Here is a list of the Entities that <strong>should not</strong> be included in the joins:</p>
  
  <pre><code>PQ
  QTY
  ANY_
  SXCMPQ
  IVLPQ
  BXITIVLPQ
  HXITPQ
  PPDPQ
  SXCMPPDPQ
  IVLPPDPQ
  IVXBPPDPQ
  IVXBPQ
  </code></pre>
  
  <p>Here is a list of Entities that <strong>should</strong> be included in the joins:  </p>
  
  <pre><code>Person
  LivingEntity
  rimEntity
  Role
  CD
  TS
  II
  EN
  </code></pre>
  
  <p>Here is the DAO method that is throwing the problem:  </p>
  
  <pre><code>@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);}
  }  
  </code></pre>
  
  <p>Here are the joins in the resulting SQL:  </p>
  
  <pre><code>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'
  </code></pre>
  
  <p>The code for the <code>Person</code> entity can be found by clicking <a href="https://jumpshare.com/v/6MFeGI0jUnzTOeUa1ZO8?b=EL4XUYfLrpIj2W1K7iji" rel="nofollow noreferrer">on this link</a>.  The code for all of the other entities can be found by clicking <a href="https://jumpshare.com/b/EL4XUYfLrpIj2W1K7iji" rel="nofollow noreferrer">on this link</a>.  </p>
  
  <p>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?</p>