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

3

12

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

Frayda answered 30/8, 2012 at 19:43 Comment(1)
Thanks for the comment. Unfortunately it is same problem without the length. I added a stack trace above to help as well.Frayda
B
14

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);
Brink answered 2/10, 2014 at 12:18 Comment(2)
Thanks, this worked for me. Interesting that the poster had something like this but with the CustomSqlType() before it. Perhaps removing that part of his mapping would have fixed it for him tooTongue
This worked for me. but it seems that it only fails for me when it is set as lazy. When it is not lazy, I already have another field with NVARCHAR(MAX) and I didnt need to add the Length mappingAzobenzene
F
10

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.

Frayda answered 30/8, 2012 at 20:22 Comment(1)
If it's mssql we use image column types. Then the mapping is just: Map(x => x.Image, "IMAGE_DATA").Length(Int32.MaxValue);Lennyleno
P
0

I got the same error while storing the big images. I resolved by adding length attribute to image field as <property name="image" length="2147483647"/>

Presidentship answered 17/7, 2020 at 17:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.