3

I recently tried to develope a "SessionWrapper". The idea behind it was to be able to switch from a Stateful Session to a Stateless Session easily, with no modifications to the DAOs and the XML mapping files.

Mapping looks like this:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="Domain" assembly=Domain">
  <class name="BatchScheduling" table="dbo.batch_scheduling">
    <id name="ID" column="batch_scheduling_id">
      <generator class="native" />
    </id>

    <property name="Name" column="batch_scheduling_name" not-null="true" />
    <property name="Description" column="batch_scheduling_description" not-null="true" />
    <property name="Type" column="batch_scheduling_type" not-null="true" />
    <property name="Cron" column="batch_scheduling_cron" not-null="true" />
    <property name="DateModified" column="batch_scheduling_date_modified" not-null="true" />

    <bag name="Parameters" cascade="all" table="dbo.batch_scheduling_parameters" lazy="true" inverse="true">
      <key column="batch_scheduling_id"/>
      <one-to-many class="BatchSchedulingParameter"/>
    </bag>

  </class>
</hibernate-mapping>

I knew that Stateless Sessions do not support lazy loading. I expected the session to eager fetch all the related objects/collections declared in the mapping.

However, when I try to access BatchScheduling.Parameters I get the following exception:

NHibernate.LazyInitializationException: Initializing[Domain.BatchScheduling#22]-failed to lazily initialize a collection of role: Domain.BatchScheduling.Parameters, no session or session was closed

Any idea?

Pierre Murasso
  • 591
  • 7
  • 14

1 Answers1

2

I knew that Stateless Sessions do not support lazy loading. I expected the session to eager fetch all the related objects/collections declared in the mapping.

That could result in the entire database being loaded into memory, and will in probably 80-90% of cases result in way more queries than are necessary and basically render the stateless session useless.

One approach you can use is to eagerly fetch the relationships you need, using something like SetFetchMode

Martin Ernst
  • 5,629
  • 2
  • 17
  • 14
  • OK so this would result in a major impact on the DAOs, and probably the overlying code. – Pierre Murasso May 15 '13 at 09:23
  • Yes - but usually you only need to do eager fetching in a few situations that are causing problems, so you could always add specific methods to your DAO's to cater for these – Martin Ernst May 15 '13 at 13:29
  • Yes but there would be an impact on overlying layers, who are currently not aware of what goes on when they call BatchScheduling.Parameters. These layers would have to explicitly call the new DAO's methods. – Pierre Murasso May 15 '13 at 14:06
  • Yes, if you really feel like it's worth it, you could try implement your own query optimizer to determine when to eager fetch relations, but that would be a huge task and I'm pretty sure it would be much easier to modify the overlying layers... – Martin Ernst May 15 '13 at 14:11