1

Hopefully some Hibernate guru can help out.

I have an object structure that looks like this:

class Customer {
    private Stuff1 stuff1;
    private Stuff2 stuff2;

    // Bazillion other fields
}

class Report {
    private Customer customer;
    private String uniqueBatchId; 

    // Bazillion other fields 
}

class AbstractSpecialReport {
    private Report report;

    //Bunch of other fields
}

class SpecialReport extends AbstractSpecialReport{
    private List<ReportParts> reportParts;           
}

All three are annotated as Hibernate entities and all associations are default (using Hibernate 3.2, so should be lazy by default.

I want to use this HQL to get the results, using ScrollableResults. I've done the required incantations to get the result set to stream.

select srpt
from SpecialReport as srpt
left join fetch srpt.report as rpt
left join fetch rpt.customer as cst
left join fetch cst.stuff1
left join fetch cst.stuff2
where rpt.uniqueBatchId = :batchId

But I get "java.sql.SQLException: Streaming result set com.mysql.jdbc.RowDataDynamic@633f8d4f is still active. No statements may be issued when any streaming result sets are open and in use on a given connection. Ensure that you have called .close() on any active streaming result sets before attempting more queries."

I have sql query logging on, and I can clearly see it trying to fetch an unrelated property on Report after it scrolled forward.

So I started growing my HQL to include these fields.

Now it looks like

select srpt
from SpecialReport as srpt
left join fetch srpt.report as rpt
left join fetch rpt.customer as cst
left join fetch rpt.field1
left join fetch rpt.field2
left join fetch rpt.field3
left join fetch rpt.field4 as child
-- now field 4 was an object that also has fields that are associations.
left join fetch child.field1
left join fetch child.field2
-- ad nauseum, this keeps going down the object tree 
left join fetch cst.stuff1
left join fetch cst.stuff2
where rpt.uniqueBatchId = :batchId

Even with about 25 join I still have more fields that are being loaded causing the same exception. I could continue to manually walk the graph, but this is taking forever, and I feel like this shouldn't be necessary. Looking through the Hibernate code it seems the TwoPhaseLoad called by the scrolling tries to initialize all proxies and lazy loaded fields in the objects, which necessarily breaks the requirement that no other sql queries be executed while a scroll is running. Does this make sense to anyone out there?

3martini
  • 510
  • 2
  • 13

1 Answers1

1

XxxToOne associations are eager by default. Annotate them as lazy if you don't want Hibernate to load them eagerly.

Moreover, a SpecialReport is a Report, so the following join doesn't make much sense:

from SpecialReport as srpt
left join fetch srpt.report as rpt
JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • That was a error in my sketch of the code, SpecialReport does not extend Report in reality. I will check the *ToOne associations though, did not realize they were Eager. – 3martini Nov 15 '12 at 22:45