NHibernate
  1. NHibernate
  2. NH-2484

Regression - Binary Blob SerializationException - MSSQL 2k8 / varbinary(max)

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: 3.0.0.GA
    • Fix Version/s: 3.1.0
    • Component/s: Core
    • Labels:
      None

      Description

      Hi,
      I have upgraded from NHibernate 2.1 to NHibernate 3.0 GA and I have hit a regression.
      I have an entity with an Image property of type System.Drawing.Image and I have mapped it like
      this:

      <property name="Image" type="System.Drawing.Image, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
      <column name="Image" length="2147483647" not-null="false" />
      </property>`

      The Image column in the table is of type varbinary(MAX) in a MySQL Server 2008 Express database and I am using the MsSql2008 dialect.

      While in NHibernate 2.1 this works perfectly fine in NHibernate 3.0 GA it breaks with the exception below when retrieving the entity back from the database:

      If I serialize the Image myself with a BinaryFormatter the resulting byte array is more than 8000 bytes, but I see that the NHibernate code is deserializing only the first 8000 bytes. Maybe varbinary(MAX) is not handled correctly?

      NHibernate.Type.SerializationException was unhandled by user code
      Message=Could not deserialize a serializable property:
      Source=NHibernate
      StackTrace:
      at NHibernate.Type.SerializableType.FromBytes(Byte[] bytes) in d:\CSharp\NH\nhibernate\src\NHibernate\Type\SerializableType.cs:line 150
      at NHibernate.Type.SerializableType.Get(IDataReader rs, Int32 index) in d:\CSharp\NH\nhibernate\src\NHibernate\Type\SerializableType.cs:line 67
      at NHibernate.Type.NullableType.NullSafeGet(IDataReader rs, String name) in d:\CSharp\NH\nhibernate\src\NHibernate\Type\NullableType.cs:line 253
      at NHibernate.Type.NullableType.NullSafeGet(IDataReader rs, String[] names, ISessionImplementor session, Object owner) in d:\CSharp\NH\nhibernate\src\NHibernate\Type\NullableType.cs:line 195
      at NHibernate.Type.AbstractType.Hydrate(IDataReader rs, String[] names, ISessionImplementor session, Object owner) in d:\CSharp\NH\nhibernate\src\NHibernate\Type\AbstractType.cs:line 131
      at NHibernate.Persister.Entity.AbstractEntityPersister.Hydrate(IDataReader rs, Object id, Object obj, ILoadable rootLoadable, String[][] suffixedPropertyColumns, Boolean allProperties, ISessionImplementor session) in d:\CSharp\NH\nhibernate\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs:line 2505
      at NHibernate.Loader.Loader.LoadFromResultSet(IDataReader rs, Int32 i, Object obj, String instanceClass, EntityKey key, String rowIdAlias, LockMode lockMode, ILoadable rootPersister, ISessionImplementor session) in d:\CSharp\NH\nhibernate\src\NHibernate\Loader\Loader.cs:line 980
      at NHibernate.Loader.Loader.InstanceNotYetLoaded(IDataReader dr, Int32 i, ILoadable persister, EntityKey key, LockMode lockMode, String rowIdAlias, EntityKey optionalObjectKey, Object optionalObject, IList hydratedObjects, ISessionImplementor session) in d:\CSharp\NH\nhibernate\src\NHibernate\Loader\Loader.cs:line 935
      at NHibernate.Loader.Loader.GetRow(IDataReader rs, ILoadable[] persisters, EntityKey[] keys, Object optionalObject, EntityKey optionalObjectKey, LockMode[] lockModes, IList hydratedObjects, ISessionImplementor session) in d:\CSharp\NH\nhibernate\src\NHibernate\Loader\Loader.cs:line 867
      at NHibernate.Loader.Loader.GetRowFromResultSet(IDataReader resultSet, ISessionImplementor session, QueryParameters queryParameters, LockMode[] lockModeArray, EntityKey optionalObjectKey, IList hydratedObjects, EntityKey[] keys, Boolean returnProxies) in d:\CSharp\NH\nhibernate\src\NHibernate\Loader\Loader.cs:line 322
      at NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) in d:\CSharp\NH\nhibernate\src\NHibernate\Loader\Loader.cs:line 453
      at NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) in d:\CSharp\NH\nhibernate\src\NHibernate\Loader\Loader.cs:line 236
      at NHibernate.Loader.Loader.LoadEntity(ISessionImplementor session, Object id, IType identifierType, Object optionalObject, String optionalEntityName, Object optionalIdentifier, IEntityPersister persister) in d:\CSharp\NH\nhibernate\src\NHibernate\Loader\Loader.cs:line 1396
      at NHibernate.Loader.Entity.AbstractEntityLoader.Load(ISessionImplementor session, Object id, Object optionalObject, Object optionalId) in d:\CSharp\NH\nhibernate\src\NHibernate\Loader\Entity\AbstractEntityLoader.cs:line 42
      at NHibernate.Loader.Entity.AbstractEntityLoader.Load(Object id, Object optionalObject, ISessionImplementor session) in d:\CSharp\NH\nhibernate\src\NHibernate\Loader\Entity\AbstractEntityLoader.cs:line 37
      at NHibernate.Persister.Entity.AbstractEntityPersister.Load(Object id, Object optionalObject, LockMode lockMode, ISessionImplementor session) in d:\CSharp\NH\nhibernate\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs:line 3436
      at NHibernate.Event.Default.DefaultLoadEventListener.LoadFromDatasource(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options) in d:\CSharp\NH\nhibernate\src\NHibernate\Event\Default\DefaultLoadEventListener.cs:line 342
      at NHibernate.Event.Default.DefaultLoadEventListener.DoLoad(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options) in d:\CSharp\NH\nhibernate\src\NHibernate\Event\Default\DefaultLoadEventListener.cs:line 320
      at NHibernate.Event.Default.DefaultLoadEventListener.Load(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options) in d:\CSharp\NH\nhibernate\src\NHibernate\Event\Default\DefaultLoadEventListener.cs:line 104
      at NHibernate.Event.Default.DefaultLoadEventListener.ProxyOrLoad(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options) in d:\CSharp\NH\nhibernate\src\NHibernate\Event\Default\DefaultLoadEventListener.cs:line 160
      at NHibernate.Event.Default.DefaultLoadEventListener.OnLoad(LoadEvent event, LoadType loadType) in d:\CSharp\NH\nhibernate\src\NHibernate\Event\Default\DefaultLoadEventListener.cs:line 87
      at NHibernate.Impl.SessionImpl.FireLoad(LoadEvent event, LoadType loadType) in d:\CSharp\NH\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 2457
      at NHibernate.Impl.SessionImpl.Get(String entityName, Object id) in d:\CSharp\NH\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 1336
      at NHibernate.Impl.SessionImpl.Get(Type entityClass, Object id) in d:\CSharp\NH\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 1275
      at NHibernate.Impl.SessionImpl.GetT(Object id) in d:\CSharp\NH\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 1259
      at HealthyLiving.DataAccess.Repositories.PolymorphicRepository`1.FindByIdTEntity(Object id) in C:\Users\Ivan\Documents\Dropbox\projects\HealthyLiving\src\HealthyLiving.DataAccess\Repositories\PolymorphicRepository.cs:line 28
      at HealthyLiving.DataAccess.Repositories.Repository`1.FindById(Object id) in C:\Users\Ivan\Documents\Dropbox\projects\HealthyLiving\src\HealthyLiving.DataAccess\Repositories\Repository.cs:line 28
      at HealthyLiving.Web.Controllers.FoodController.Details(Int32 id) in C:\Users\Ivan\Documents\Dropbox\projects\HealthyLiving\src\HealthyLiving.Web\Controllers\FoodController.cs:line 24
      at lambda_method(ExecutionScope , ControllerBase , Object[] )
      at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
      at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
      at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
      at System.Web.Mvc.ControllerActionInvoker.<>c_DisplayClassd.<InvokeActionMethodWithFilters>b_a()
      at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
      InnerException: System.Runtime.Serialization.SerializationException
      Message=End of Stream encountered before parsing was completed.
      Source=mscorlib
      StackTrace:
      at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()
      at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
      at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
      at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream)
      at NHibernate.Type.SerializableType.FromBytes(Byte[] bytes) in d:\CSharp\NH\nhibernate\src\NHibernate\Type\SerializableType.cs:line 146
      InnerException:

      1. MsSql2008Dialect.cs
        0.7 kB
        Julian Maughan
      2. NH-2484-fix.patch
        2 kB
        Ivan Zlatev

        Issue Links

          Activity

          Hide
          Ivan Zlatev added a comment -

          Thanks a lot!

          Show
          Ivan Zlatev added a comment - Thanks a lot!
          Hide
          Michael Teper added a comment -

          Until 3.0.1, the following mapping seems to do the trick:

          <property name="Data" type="Serializable" length="2147483647" />

          Show
          Michael Teper added a comment - Until 3.0.1, the following mapping seems to do the trick: <property name="Data" type="Serializable" length="2147483647" />
          Hide
          Tim Hughes added a comment -

          Is there an ETA on version 3.0.1? I too am running into the 8k barrier. I tried the mapping described by Michael Teper and that doesn't work. I'm trying to save image data to a database, but every image I upload after making Michael's change has an additional 28 bytes added. The database column I'm writing to is defined as a varbinary(max). The C# class defines the property that holds the data as type byte[]. The mapping file has the exact property mapping as defined by Michael (with the Name attribute changed of course). This did work with version 2.1.2.
          Unfortunately I am days away from moving my code into production and would like to get access to version 3.0.1 ASAP.

          Show
          Tim Hughes added a comment - Is there an ETA on version 3.0.1? I too am running into the 8k barrier. I tried the mapping described by Michael Teper and that doesn't work. I'm trying to save image data to a database, but every image I upload after making Michael's change has an additional 28 bytes added. The database column I'm writing to is defined as a varbinary(max). The C# class defines the property that holds the data as type byte[]. The mapping file has the exact property mapping as defined by Michael (with the Name attribute changed of course). This did work with version 2.1.2. Unfortunately I am days away from moving my code into production and would like to get access to version 3.0.1 ASAP.
          Hide
          Tim Hughes added a comment -

          Sorry I meant ETA on version 3.1.0.

          Show
          Tim Hughes added a comment - Sorry I meant ETA on version 3.1.0.
          Hide
          Julian Maughan added a comment -

          The 3.1 release was slated for the end of this month, so keep watching...

          Show
          Julian Maughan added a comment - The 3.1 release was slated for the end of this month, so keep watching...

            People

            • Assignee:
              Unassigned
              Reporter:
              Ivan Zlatev
            • Votes:
              2 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Who's Looking?