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

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.Get[T](Object id) in d:\CSharp\NH\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 1259
at HealthyLiving.DataAccess.Repositories.PolymorphicRepository`1.FindById[TEntity](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:

Environment

None

Attachments

3

Activity

Show:

Julian Maughan February 25, 2011 at 1:50 AM

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

Tim Hughes February 23, 2011 at 3:05 PM

Sorry I meant ETA on version 3.1.0.

Tim Hughes February 23, 2011 at 3:03 PM

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.

Michael Teper January 31, 2011 at 12:02 AM

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

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

Ivan Zlatev January 26, 2011 at 7:19 AM

Thanks a lot!

Fixed

Details

Assignee

Reporter

Components

Fix versions

Affects versions

Priority

Who's Looking?

Open Who's Looking?

Created January 3, 2011 at 6:45 AM
Updated June 3, 2012 at 10:56 AM
Resolved January 26, 2011 at 7:14 AM
Who's Looking?