Skip to content

Guards against use of a disposed session factory #3120

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

Merged
merged 1 commit into from
Aug 23, 2022

Conversation

fredericDelaporte
Copy link
Member

@fredericDelaporte fredericDelaporte commented Aug 21, 2022

Help diagnose #3026 reports.

I suspect those reports are due to user code errors, using a disposed session factory. It appears a disposed session factory does not throw when used. It lets things fail quite later with harder to understand exceptions. This leads to bug reports for what is likely user bugs.

This PR currently targets 5.3.x. But this may be considered as too much of a possible breaking change for this branch, even if using a disposed session factory is a bug on user side.
In my opinion it is ok to have it in 5.3.x.

Comment on lines 474 to 475
CheckNotDisposed();
return eventListeners;
Copy link
Member Author

Choose a reason for hiding this comment

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

The session factory closing Destroy the event listeners, so better guard against any later use of them.

Comment on lines 520 to 521
CheckNotDisposed();
return new SessionBuilderImpl(this);
Copy link
Member Author

Choose a reason for hiding this comment

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

I have mostly protected accesses to resources destroyed or disposed by the session factory closing, except here and in stateless equivalent, where there is no direct accesses to these resources. But that is the main usage of session factories, so, better to directly throw here when using it on a disposed factory.

Comment on lines 589 to 591
CheckNotDisposed();
IEntityPersister value;
if (entityPersisters.TryGetValue(entityName, out value) == false)
Copy link
Member Author

Choose a reason for hiding this comment

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

entityPersisters have their cache property destroyed by the factory closing, so guarding against their use. This also causes most session usages to throw if their session factory is disposed, which is also the aim of this PR.

Comment on lines 606 to 608
CheckNotDisposed();
ICollectionPersister value;
if (collectionPersisters.TryGetValue(role, out value) == false)
Copy link
Member Author

Choose a reason for hiding this comment

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

Same here, their cache is destroyed by the factory closing.

Comment on lines 1125 to 1127
CheckNotDisposed();
return
_allCacheRegions
Copy link
Member Author

Choose a reason for hiding this comment

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

Caches are destroyed by the closing.

Comment on lines 1140 to 1142
CheckNotDisposed();
_allCacheRegions.TryGetValue(regionName, out var result);
return result;
Copy link
Member Author

Choose a reason for hiding this comment

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

_allCacheRegions is also accessed by private GetCache, which I do not guard because it is currently called only by already directly guarded methods or upon initialization of the session factory.

Comment on lines 1169 to 1170
if (queryCache != null)
CheckNotDisposed();
Copy link
Member Author

Choose a reason for hiding this comment

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

Not sure I should have that if. Done for consistency with EvictQueries.

Comment on lines 864 to 870
private void CheckNotDisposed()
{
if (disposed)
{
throw new ObjectDisposedException($"Session factory {Name} with id {Uuid}");
}
}
Copy link
Member Author

@fredericDelaporte fredericDelaporte Aug 21, 2022

Choose a reason for hiding this comment

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

I am going to change this to CheckNotClosed, because we can close a factory without disposing it, and closing it is enough to cause the reported troubles.

@hazzik hazzik enabled auto-merge (squash) August 23, 2022 23:50
@hazzik hazzik added the t: Fix label Aug 23, 2022
@hazzik hazzik merged commit d903bb2 into nhibernate:5.3.x Aug 23, 2022
@fredericDelaporte
Copy link
Member Author

I had to force the MyGet publishing on TeamCity. Maybe I should have just waited, but I was not seeing any reason for it to have not run after the TeamCity "Release" build was finished.

@fredericDelaporte fredericDelaporte deleted the GH3026 branch August 25, 2022 18:27
@hazzik hazzik removed the t: Fix label Aug 31, 2022
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.

2 participants