‘System.Reflection.TargetException’ if merge a entity which contains a lazy load property

Description

I have an entity which has a laze loaded property.
Once I create a new instance of this entity, and use session.merge() method(), it will throw out an exception:

在 System.Reflection.RuntimeMethodInfo.CheckConsistency(Object target)
在 System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
在 System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
在 System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
在 NHibernate.Intercept.DefaultDynamicLazyFieldInterceptor.Intercept(InvocationInfo info) 位置 DefaultDynamicLazyFieldInterceptor.cs: line 62
在 AttachmentEntityProxy.get_FieldInterceptor()
在 NHibernate.Intercept.FieldInterceptionHelper.ExtractFieldInterceptor(Object entity) 位置 FieldInterceptionHelper.cs: line 33
在 NHibernate.Tuple.Entity.PocoEntityTuplizer.HasUninitializedLazyProperties(Object entity) 位置 PocoEntityTuplizer.cs: line 271
在 NHibernate.Tuple.Entity.AbstractEntityTuplizer.ShouldGetAllProperties(Object entity) 位置 AbstractEntityTuplizer.cs: line 388
在 NHibernate.Tuple.Entity.PocoEntityTuplizer.GetPropertyValues(Object entity) 位置 PocoEntityTuplizer.cs: line 240
在 NHibernate.Persister.Entity.AbstractEntityPersister.GetPropertyValues(Object obj, EntityMode entityMode) 位置 AbstractEntityPersister.cs: line 3875
在 NHibernate.Event.Default.DefaultMergeEventListener.CopyValues(IEntityPersister persister, Object entity, Object target, ISessionImplementor source, IDictionary copyCache, ForeignKeyDirection foreignKeyDirection) 位置 DefaultMergeEventListener.cs: line 484
在 NHibernate.Event.Default.DefaultMergeEventListener.MergeTransientEntity(Object entity, String entityName, Object requestedId, IEventSource source, IDictionary copyCache) 位置 DefaultMergeEventListener.cs: line 232
在 NHibernate.Event.Default.DefaultMergeEventListener.EntityIsTransient(MergeEvent event, IDictionary copyCache) 位置 DefaultMergeEventListener.cs: line 207
在 NHibernate.Event.Default.DefaultMergeEventListener.OnMerge(MergeEvent event, IDictionary copiedAlready) 位置 DefaultMergeEventListener.cs: line 167
在 NHibernate.Event.Default.DefaultMergeEventListener.OnMerge(MergeEvent event) 位置 DefaultMergeEventListener.cs: line 42
在 NHibernate.Impl.SessionImpl.FireMerge(MergeEvent event) 位置 SessionImpl.cs: line 2480
在 NHibernate.Impl.SessionImpl.Merge(String entityName, Object obj) 位置 SessionImpl.cs: line 1007
在 NHibernate.Impl.SessionImpl.Merge(Object obj) 位置 SessionImpl.cs: line 1025
在 NHibernate.Impl.SessionImpl.Merge(T entity) 位置 SessionImpl.cs: line 1013

Environment

None

Activity

Show:

Alex Zaytsev January 17, 2013 at 6:29 AM

It seems that it should be fixed by in master. Please provide a test case.

Nathan Xu December 14, 2012 at 3:59 AM

Hi Oskar,
I noticed that if I change the line 270 code from ' if (EntityMetamodel.HasLazyProperties)' to ' if (EntityMetamodel.HasLazyProperties && !(entity is IProxy))' in class 'PocoEntityTuplizer', the error will be disappeared.
Could you please verify if the above change is correct or not?
Thank you very much.

Nathan Xu December 13, 2012 at 9:44 AM

I also try to debug it, and I found that this source line "info.TargetMethod.Invoke(TargetInstance, info.Arguments)" in class DefaultDynamicLazyFieldInterceptor seems like the root cause.
The parameter 'TargetInstance' is not a 'XXXProxy' instance, instead of that, it is a 'XXX' object, but I did not find where the targetInstance is instanced.

Nathan Xu December 13, 2012 at 9:41 AM

Hi Oskar,
Thanks for your reply.
The case is I have a table which includes some binary content,
e.g:
AttachmentTable
{
Id Guid,
Name varchar(32),
FileContent varbinary(max)
}

for the performance reason, I want to only get file names without its content, so I set the FileContent to 'lazyload'.

For some other reason(Add an new attachment to another existing object), some times I have to merge the entity, with the below test case, you should can reproduce this issue.

Create an new attachment entity, then call session.Merge():
AttachmentEntity attachment = new AttachmentEntity();
attachment.Name = "testFile";
attachment.BytesContent = uploadingFileContent();
attachment.ContentType = "zip";
attachment.Size = attachment.BytesContent.Length;

_access.RunInSession(session =>
{
session.Merge(attachment);
});

Then the exception is throw out.

Oskar Berggren December 12, 2012 at 11:26 AM

There should be more information available from the exception I think. E.g. the message and InnerException.

Can you create a minimal test case that demonstrates the problem?

Details

Assignee

Reporter

Labels

Components

Affects versions

Priority

Who's Looking?

Open Who's Looking?

Created December 10, 2012 at 9:46 AM
Updated January 17, 2013 at 7:40 AM
Who's Looking?