Hi,

Thank you for sharing your insights. I now better understand the scenario. 
I appreciate your information related to my queries. I agree that my 
implementation could potentially cause problems within other NHibernate 
internals at runtime, which is why I mentioned that I'm not entirely sure 
about its broader implications. My focus was primarily on developing this 
implementation for a specific case. However, I understand that NHibernate 
isn't limited to just these scenarios—it has a wealth of features and 
internal APIs. Therefore, I wouldn't recommend using the exact code 
implementation for broader use cases without thorough validation and 
testing.

In real-world scenarios, we're often not limited to static tables and 
views; sometimes, database schemas need to change based on user 
requirements. This creates challenges that extend beyond the existing 
NHibernate implementation. Adding features like dynamic schema alterations 
to an ORM as robust as NHibernate could significantly impact the 
development process.

Regarding your point about *Dispose()* and *Close()* methods in NHibernate, 
I understand that they clear the cache allocated for specific persistent 
and collection models. I acknowledge that I overlooked handling this in my 
method.

As for the reason behind removing the readonly modifiers, it was to allow 
altering existing mapper properties and adding the altered mapper into the 
SessionFactory. Since both would have the same EntityName, I needed to 
replace the existing key-value pair (instead of removing it) when altering 
the schema.

I also appreciate your suggestion of maintaining multiple small 
SessionFactory instances. While some of our tables are related, I plan to 
explore splitting them into multiple SessionFactory instances based on your 
advice. I'll analyze the memory footprints and associated challenges in my 
application accordingly.

I realize that I'm not fully familiar with some of NHibernate's internals, 
which is why I'm seeking verification on the exact purpose of immutability 
and whether there's a way to test it using your test suite.

*My implementation idea is straightforward:* I disabled the entire 
second-level cache in the configuration to avoid certain issues in our 
application, so preparing the second-level cache isn't necessary for us. We 
build the SessionFactory with our application's POCO objects and XML 
mappers, and at that point, the initialization is complete, so it doesn't 
affect the flow. After that, I add or alter tables and handle it according 
to your documentation on dynamic persistent models (by creating an XML 
mapper string at runtime using System.Xml.Linq). This works well. Then, I 
prepare the configuration, call the Dispose method for the old 
SessionFactory, and build a new one. My concern is that re-preparing all 
caches, HQL, etc., for all my entities again seems unnecessary. I'm only 
adding a single mapper, but the iteration goes to n+1, which increases both 
time and memory consumption. That's why I'm looking for a solution from 
within NHibernate.

Every development needs to be consistent and tolerant. I believe this could 
be an implementable feature for the existing NHibernate code and could be 
considered for future updates, especially concerning dynamic persistent 
models.

Lastly, I have another question related to your documentation and code:

In the NHibernate documentation (*Chapter 4.5. Tuplizers*), you mention 
that it's possible to extends 
NHibernate.Tuple.Entity.DynamicMapEntityTuplizer and create a custom 
tuplizer. However, in the code, this tuplizer has an *internal *constructor. 
If I'm using NHibernate as a NuGet package, how can I implement this custom 
tuplizer? Could you please verify this and consider changing the 
constructor to *public*?

On Saturday 24 August 2024 at 01:01:43 UTC+5:30 Frédéric Delaporte wrote:

> > I am actually trying to alter the existing NHibernate code to add newly 
> added PersistentClass instances and CollectionModels as well. 
>
> You take the risk of freezing the NHibernate version you are using due to 
> the complexity of the conflicts you may have to resolve for updating your 
> modified factory implementation to the latest NHibernate version. Take the 
> current latest version of the source code and give it a try, to see what I 
> mean.
>
> Your solution is a bold endeavor in my opinion. You will be mostly on your 
> own, I fear.
>
> Another solution could be to re-architecture your application to use many 
> small independent session factories, instead of having a single huge one. 
> Are all these entities all inter-related through associations? Or could 
> they be spill in many independent schema? With the later, independent 
> smaller session factories should work well. And a schema change would need 
> to rebuild only one small session factories instead of the huge single one. 
> It should solve your current troubles.
>
> > Could you please verify the code changes I have attached below and also 
> explain any cases where this implementation might break or throw exceptions
>
> Doing this thoroughly would require much more time than what I am willing 
> to spend. I already do not understand why have you removed most of the 
> readonly modifiers, while seemingly not assigning anything new to most of 
> the members you have changed. (Just in case you would not know this: the 
> readonly modifier does not cause instances assigned to readonly members to 
> be immutable. It only causes the members to be assignable only at class 
> initialization, and no more at a later time.)
>
> Your updating code also looks like:
>  - Running operations, probably disabled by your config, that should not 
> be supported for an incremental update, like creating the whole schema.
>  - Running initialization code on the whole persisters list. Is that the 
> right choice, or should it be run only on the newly added ones? Or 
> something else? Analyzing what does these initializations is required to 
> know what is needed. I do not want to dive into this potential rabbit hole.
>  - Recreating the second level query cache entirely (thus needing to 
> remove the readonly modifiers for these members). It looks unnecessary to 
> me. Again, I have not checked thoroughly. Moreover the code forgets to 
> dispose the old one prior to re-assigning a new one. (See Close method.)
>  - Other small "reintializations" seem likewise unneeded.
>
> On Friday, August 23, 2024 at 8:43:15 PM UTC+2 [email protected] 
> wrote:
>
>> Hello,
>>
>> Thank you so much for the answer. You explained the reason behind 
>> implementing an immutable SessionFactory—primarily due to thread safety and 
>> performance concerns. Making the SessionFactory immutable was a key 
>> decision.
>>
>> Let me explain my current scenario.
>>
>> I’m facing significant challenges with NHibernate in my .NET application, 
>> particularly around dynamically creating tables and altering schemas at 
>> runtime. My application needs to create millions of tables concurrently and 
>> occasionally modify their schemas. Currently, each table creation or schema 
>> alteration involves creating new Configuration and SessionFactory 
>> instances, leading to severe memory overhead and performance bottlenecks.
>>
>> I understand that SessionFactory is immutable, but in my scenario, adding 
>> newly persistent entities to the existing SessionFactory is preferable to 
>> building a new one. Despite my efforts, rebuilding the SessionFactory is 
>> costly (e.g., over 6 GB for 50,000 mappers and 12.27 GB for 100,000 
>> mappers).
>>
>> Based on this, we need a mutable SessionFactory. I am actually trying to 
>> alter the existing NHibernate code to add newly added PersistentClass 
>> instances and CollectionModels as well. It is working well, but we are not 
>> entirely sure about the implications of this alteration, given the 
>> fundamental reason for maintaining an immutable SessionFactory—specifically 
>> the performance aspect. I need to explain that while we may reduce memory 
>> complexity, we could potentially introduce other issues.
>>
>> Could you please verify the code changes I have attached below and also 
>> explain any cases where this implementation might break or throw 
>> exceptions? Locking the SessionFactory for a few milliseconds is crucial 
>> for managing our application to run with low memory usage. Thank you.
>>
>> [image: NHibernate Overall MemoryManagement.png]
>>
>> [image: AddMapperInSessionFactory.png][image: SessionFactoryImpl.png]
>> On Friday 23 August 2024 at 01:56:19 UTC+5:30 Frédéric Delaporte wrote:
>>
>>> Hi,
>>>
>>> A session factory is thread safe once built. Thread safety is hard to 
>>> get right with mutable objects. And thread safe mutability incurs using 
>>> locks, which hurts performances.
>>>
>>> On Thursday, August 22, 2024 at 10:20:53 PM UTC+2 [email protected] 
>>> wrote:
>>>
>>>> Hello Everyone,
>>>>
>>>> I hope you're all doing well.
>>>>
>>>> I'm currently working with NHibernate and have been reviewing some of 
>>>> its code on GitHub. I noticed that every time we add or modify mappers in 
>>>> the configuration, it seems necessary to rebuild the SessionFactory.
>>>>
>>>> Why can't we simply update the newly added mappers in the existing 
>>>> SessionFactory? Is it mandatory to rebuild the SessionFactory each time? 
>>>> What is the rationale behind maintaining the SessionFactory as immutable? 
>>>> If there are any vulnerabilities or risks with this approach, could you 
>>>> provide example scenarios?
>>>>
>>>

-- 
You received this message because you are subscribed to the Google Groups 
"nhusers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/nhusers/8e899eec-af1a-464e-aafa-0992f7831aadn%40googlegroups.com.

Reply via email to