why are estimated rows exponentially increasing with each join?
As you're using hibernate this is going to be a bit cumbersome. You can 'guide' the optimizer by telling him how to do the joins.
For example select * from a inner hash join b on a.x = b.x will tell the optimizer to do a hash join. It could also be a merge join or a loop hint.
This might result into writing the sql queries manually. Using hints should also be one of the last things to try. Your tables might change over time and the hints might not apply/be good for the performance at a later stage (mostly when switching from development to production).