6

I've been trying to upgrade a project using fluent nhibernate 1.2 and NHibernate 3.1 to FNH 1.3 and NH 3.2, and it all seems to work except now Im getting an exception on a .List() command.

The exception type & message are... NHibernate.Exceptions.GenericADOException Unable to perform find[SQL: SQL not available] and the inner exception... System.IndexOutOfRangeException Index was outside the bounds of the array.

I have profiled the query in SQL Server and I think its a problem with the AppFabric cache and NH 3.2 because the query generated by NH is fine.

Nothing in the code has changed just my FNH and NH references.

Below is my query in C#...

return ResourceRepository.Query()
                        .LeftOuterJoin(r => r.ResourceCorpus, () => resourceCorpusAlias)
                        .LeftOuterJoin(r => r.ResourceType, () => resourceTypeAlias)
                        .Cachable()
                        .List();

and below is the mapping hbm generated by FNH which hasnt changed between versions...

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-import="false">
  <class xmlns="urn:nhibernate-mapping-2.2" schema="[Reference]" mutable="false" name="MyAssembly.Reference.Resource, MyAssembly.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="`Resource`">
    <cache usage="read-only" />
    <id name="Id" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" unsaved-value="0">
      <column name="Id" />
      <generator class="assigned" />
    </id>
    <bag name="ResourceCorpus" mutable="false">
      <cache usage="read-only" />
      <key>
        <column name="ResourceId" />
      </key>
      <one-to-many class="MyAssembly.Reference.ResourceCorpus, MyAssembly.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    </bag>
    <property name="TokenName" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="TokenName" />
    </property>
    <property name="Description" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Description" />
    </property>
    <many-to-one class="MyAssembly.Reference.ResourceType, MyAssembly.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" fetch="select" name="ResourceType">
      <column name="ResourceTypeId" />
    </many-to-one>
  </class>
</hibernate-mapping>

In the NH 3.2 source the following line is where the exception is thrown...

if (nonCacheable != null && nonCacheable[i])

and the call stack...

>   NHibernate.dll!NHibernate.Type.TypeHelper.Disassemble(object[] row, NHibernate.Type.ICacheAssembler[] types, bool[] nonCacheable, NHibernate.Engine.ISessionImplementor session, object owner)
    NHibernate.dll!NHibernate.Cache.StandardQueryCache.Put(NHibernate.Cache.QueryKey key, NHibernate.Type.ICacheAssembler[] returnTypes, System.Collections.IList result, bool isNaturalKeyLookup, NHibernate.Engine.ISessionImplementor session)
    NHibernate.dll!NHibernate.Loader.Loader.PutResultInQueryCache(NHibernate.Engine.ISessionImplementor session, NHibernate.Engine.QueryParameters queryParameters, NHibernate.Type.IType[] resultTypes, NHibernate.Cache.IQueryCache queryCache, NHibernate.Cache.QueryKey key, System.Collections.IList result)
    NHibernate.dll!NHibernate.Loader.Loader.ListUsingQueryCache(NHibernate.Engine.ISessionImplementor session, NHibernate.Engine.QueryParameters queryParameters, Iesi.Collections.Generic.ISet<string> querySpaces, NHibernate.Type.IType[] resultTypes)
    NHibernate.dll!NHibernate.Loader.Criteria.CriteriaLoader.List(NHibernate.Engine.ISessionImplementor session)
    NHibernate.dll!NHibernate.Impl.SessionImpl.List(NHibernate.Impl.CriteriaImpl criteria, System.Collections.IList results)
    NHibernate.dll!NHibernate.Impl.CriteriaImpl.List(System.Collections.IList results)
    NHibernate.dll!NHibernate.Impl.CriteriaImpl.List<MyAssembly.Reference.Resource>()

So any help would be greatly appreciated, if you want any more information let me know, thanks.

electricsheep
  • 5,114
  • 9
  • 37
  • 41
  • How are you talking to AppFabric? Are you using the Velocity provider from NHContrib? – PhilPursglove Jan 19 '12 at 12:29
  • Nope we are using the using Microsoft.ApplicationServer.Caching assembly. – electricsheep Jan 19 '12 at 13:57
  • I could be (and probably am) wrong about this but I don't *think* AppFabric's the problem here. My understanding is that to use AppFabric (or any other cache) with NHibernate as a second-level cache, you need to include support for it with a provider (some details at http://nhforge.org/doc/nh/en/index.html#caches), it doesn't just happen automatically; hence my question about the provider. – PhilPursglove Jan 19 '12 at 15:13
  • Yeah, we have a provider which was working fine with 3.1 but as soon as we upgraded to 3.2 it wont work. I tried using the velocity provider rather than our custom provider and I still get the same error as before – electricsheep Jan 19 '12 at 15:50
  • The Velocity provider is broken, it only works with the betas of AppFabric. Are you using AppFabric 1.1? If so did you update your custom provider to 1.1 too? – PhilPursglove Jan 19 '12 at 16:28

1 Answers1

4

After rooting around the internet (a.k.a google) a bit more found this...

https://nhibernate.jira.com/browse/NH-2961

Turns out its a known bug in NH 3.2 thought I would post here in case anyone else is having this issue.

electricsheep
  • 5,114
  • 9
  • 37
  • 41