Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #1419 - ISession.IsDirty() shouldn't throw exception for transient many-to-one object in a session #1420

Merged
merged 8 commits into from
Nov 3, 2017

Conversation

bahusoid
Copy link
Member

@bahusoid bahusoid commented Nov 2, 2017

Fixes #1419

@fredericDelaporte fredericDelaporte self-requested a review November 2, 2017 17:07
return true;
}

if (ForeignKeys.IsTransientFast(GetAssociatedEntityName(), current, session) == true)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to use IsTransientSlow, otherwise the bug will still be there for entities having an assigned id already assigned or having an unsaved-value set as undefined. IsTransientSlow hits the db only if IsTransientFast was not able of answering, which occurs in aforementioned cases.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to have a test for this case.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fredericDelaporte, the GetEntityIdentifierIfNotUnsaved calls IsTransientFast as well.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, what will happen in case of an entity with assigned ID - the "IsDirty" method will not fail, but it will return false.

Copy link
Member Author

@bahusoid bahusoid Nov 3, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fredericDelaporte

Need to use IsTransientSlow, otherwise the bug will still be there

Are you sure? I simply reused check that lead to exception:

if (IsTransientFast(entityName, entity, session).GetValueOrDefault())
{
/***********************************************/
// TODO NH verify the behavior of NH607 test
// these lines are only to pass test NH607 during PersistenceContext porting
// i'm not secure that NH607 is a test for a right behavior
EntityEntry entry = session.PersistenceContext.GetEntry(entity);
if (entry != null)
return entry.Id;
// the check was put here to have les possible impact
/**********************************************/
entityName = entityName ?? session.GuessEntityName(entity);
string entityString = entity.ToString();
throw new TransientObjectException(
string.Format("object references an unsaved transient instance - save the transient instance before flushing or set cascade action for the property to something that would make it autosave. Type: {0}, Entity: {1}", entityName, entityString));

So in your case exception won't be thrown by GetIdentifier(current, session); method. And result will be given to identifierType.IsDirty method.

@hazzik

the "IsDirty" method will not fail, but it will return false

Why false? What IsDirty returns depends on identifierType.IsDirty call. And from my understanding it should work fine - we will simply check if identifier value is changed. And if it's new object - it should definitely change.

Copy link
Member Author

@bahusoid bahusoid Nov 3, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just in case I made a quick test with assigned id and it works OK. Should I squash it in to test commit? Or separate commit is OK?

Copy link
Member

@fredericDelaporte fredericDelaporte Nov 3, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, better add it to test commit. You may first add it as a "fixup! Test case for GH1419 (ISession.IsDirty() failed for transient many-to-one" commit and later squash it if you prefer.

Well, already added, never mind, can still be squashed later.

Ok, what will happen in case of an entity with assigned ID - the "IsDirty" method will not fail, but it will return false.

I believe IsTransientFast yields null instead in that case, but @bahusoid test seems to show I were wrong in assuming the whole case would fail. Adding tests for assigned id and unsaved-value "undefined" is definitely the way to go. (Maybe can we disregard the undefined case, using that option looks a bit like calling for troubles, I do not know why it even exist.)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was checking with Assigned Guids. Not sure why it works with integers.

Copy link
Member Author

@bahusoid bahusoid Nov 3, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hazzik I changed int to Guid in my test and it still works...
Note: My first attempt with assigned id was also failing until I realized that I forgot to map new property in parent object )

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I had the same problem ;)

@hazzik hazzik changed the title Test case and fix for GH1419 (ISession.IsDirty() shouldn't throw exception for transient many-to-one object in session) Fix #1419 - ISession.IsDirty() shouldn't throw exception for transient many-to-one object in a session Nov 3, 2017
@bahusoid
Copy link
Member Author

bahusoid commented Nov 3, 2017

Added new test as separate commit. Let me know if it needs to be rebased and squashed instead.

@hazzik
Copy link
Member

hazzik commented Nov 3, 2017

Thanks. Nice work

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants