自定义NHibernate会话实现

时间:2011-09-08 10:51:14

标签: nhibernate session

我正在使用NHibernate执行批量处理的系统。我知道NHibernate不是为批量处理而设计的,但是由于一些优化,系统正在完美地工作。

最低粒度级别的对象(即我的聚合的根)有许多字符串属性,它们不能(或者,没有意义)被建模为多个 - 一个人(例如"评论")。实际上,对应于这些属性的DB中的字段只占用很多值(例如,因为大多数 - 但不是全部 - 注释是机器生成的),结果是当对大量对象进行保湿时,会浪费大量内存。拥有成千上万个具有相同值的字符串实例。

我正在考虑通过创建我自己的NHibernate自定义类型来透明地优化这个场景,该类型通过覆盖StringType并执行字典查找以返回每个字符串的相同实例来增强NHibernate的NullSafeGet()一遍又一遍地发生。换句话说,我会执行一种自己实习的字符串。使用自定义类型允许我选择哪些对象应该是哪些属性" interned"只需在映射文件中指定此类型即可。

理想情况下,我想"坚持"将此字典放入会话中,以便此字符串池的生命周期与第一级缓存的生存期相关联。毕竟,从我们系统的角度来看,在会话及其第一级缓存初始化的同时初始化此字符串池是有意义的,并且在会话同时对字符串池进行核对。关闭。它也是一个理想的属性,通过拥有自己的私有词典,并发会话彼此完全隔离。

问题是,我无法找到一种方法来注射"将NHibernate会话自定义实现到NHibernate本身,以便IType可以在NullSafeGet()时访问它,而不是创建我自己的个人NHibernate代码分支。

有没有办法为NHibernate提供自定义会话实现?

1 个答案:

答案 0 :(得分:4)

我认为有三种不同的方法可以解决这个问题:

<强> 1。使用拦截器

在IInterceptor中,你得到:

void AfterTransactionBegin(ITransaction tx);
void BeforeTransactionCompletion(ITransaction tx);

<强> 2。打开和关闭会话:

打开和关闭会话是一个显式调用。将它包装成方法应该很容易。

public ISession OpenSession()
{
  var session = sessionFactory.CreateSession();
  StringType.Initialize();
}

你可以做得更好。我写了一个有事件的交易服务。然后,您可以处理开始事务和结束事务事件。

第3。不要将字符串缓存附加到会话

它不需要与会话相关。字符串是不可变对象,当你在会话之间混合时它不会受到伤害。为了避免缓存无限增长,您可以编写自己的缓存或使用现有的“最近使用的”-cache。在生长到一定大小后,它会抛弃最古老的物品。

这可能需要一些时间来实现,但是非常好用且易于使用。