Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NHibernate Image Storage - The length of the byte[] value exceeds the length configured

I am using Fluent NHibernate and am trying to store an image. Small images work, but larger images do not, and I receive this error when saving to the database (SQL Server):

Exception: Error dehydrating property value for CFC.Domain.Vehicle.Image

Inner Exception: The length of the byte[] value exceeds the length configured in the mapping/parameter.

Here is my mapping:

mapping.Table("Vehicle");
mapping.Id(x => x.Id, "VehicleID");
mapping.Map(x => x.Year).Not.Nullable();
mapping.Map(x => x.Image).CustomSqlType("VARBINARY(MAX)").Length(int.MaxValue);

The "Image" property is a byte[].

Note the CustomSqlType and the length, which creates the proper nvarchar(max) column in the database. I've read countless of other posts talking about similar issues, but none cover this specific error. It isn't that the data is being truncated and then saved, it just errors out before ever sending the SQL query.

The image I am testing with is just the standard Windows 7 sample images (Penguins.jpg of course) but an image around 1kb works fine.

I appreciate the help! Here is the beginning of the stack trace if it helps.

[HibernateException: The length of the byte[] value exceeds the length configured in the mapping/parameter.]
NHibernate.Type.AbstractBinaryType.Set(IDbCommand cmd, Object value, Int32 index) +207
NHibernate.Type.NullableType.NullSafeSet(IDbCommand cmd, Object value, Int32 index) +397
NHibernate.Type.NullableType.NullSafeSet(IDbCommand st, Object value, Int32 index, Boolean[] settable, ISessionImplementor session) +62
NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Object id, Object[] fields, Object rowId, Boolean[] includeProperty, Boolean[][] includeColumns, Int32 table, IDbCommand statement, ISessionImplementor session, Int32 index) +350

[PropertyValueException: Error dehydrating property value for CFC.Domain.Vehicle.Image]
NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Object id, Object[] fields, Object rowId, Boolean[] includeProperty, Boolean[][] includeColumns, Int32 table, IDbCommand statement, ISessionImplementor session, Int32 index) +510
NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Object id, Object[] fields, Boolean[] includeProperty, Boolean[][] includeColumns, Int32 j, IDbCommand st, ISessionImplementor session) +59 NHibernate.Persister.Entity.GeneratedIdentifierBinder.BindValues(IDbCommand ps) +79
NHibernate.Id.Insert.AbstractReturningDelegate.PerformInsert(SqlCommandInfo insertSQL, ISessionImplementor session, IBinder binder) +102
NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object[] fields, Boolean[] notNull, SqlCommandInfo sql, Object obj, ISessionImplementor session) +265
NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object[] fields, Object obj, ISessionImplementor session) +358
NHibernate.Action.EntityIdentityInsertAction.Execute() +262
NHibernate.Engine.ActionQueue.Execute(IExecutable executable) +56
NHibernate.Event.Default.AbstractSaveEventListener.PerformSaveOrReplicate(Object entity, EntityKey key, IEntityPersister persister, Boolean useIdentityColumn, Object anything, IEventSource source, Boolean requiresImmediateIdAccess) +811
NHibernate.Event.Default.AbstractSaveEventListener.PerformSave(Object entity, Object id, IEntityPersister persister, Boolean useIdentityColumn, Object anything, IEventSource source, Boolean requiresImmediateIdAccess) +543
NHibernate.Event.Default.AbstractSaveEventListener.SaveWithGeneratedId(Object entity, String entityName, Object anything, IEventSource source, Boolean requiresImmediateIdAccess) +257

like image 421
jkriddle Avatar asked Aug 30 '12 19:08

jkriddle


2 Answers

I know it's a little late to be posting a reply but I just came across this exact same error. Below was my resolution - hopefully it helps someone else in the future.

I changed:

Map(x => x.ByteArrayProperty);

to:

Map(x => x.ByteArrayProperty).Length(int.MaxValue);
like image 89
spyter Avatar answered Nov 05 '22 05:11

spyter


Sigh, sometimes after 2 days of research you just have to post a question to StackOverflow to find the answer right after.

I'm not sure of the underlying reason, but specifying the property directly when mapping was the problem. To resolve the issue I ended up creating a new "BinaryLengthConvention" below.

public class BinaryColumnLengthConvention : IPropertyConvention, IPropertyConventionAcceptance
{
    public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria)
    {
        criteria.Expect(x => x.Property.PropertyType == typeof(byte[]));
    }

    public void Apply(IPropertyInstance instance)
    {
        instance.Length(2147483647);
        instance.CustomSqlType("varbinary(MAX)");
    }
}

Magically it all started working. Hopefully someone else that searches for that error message finds this useful.

like image 42
jkriddle Avatar answered Nov 05 '22 04:11

jkriddle