我正在实现一个基于实体属性值的持久性机制.所有数据库访问都是通过Hibernate完成的.我有一个包含节点路径的表,它非常简单,只是一个id,一个路径(字符串)路径数量很少,大约有几千个.
主表有数百万行,而不是重复路径,我已经规范化了自己的表的路径.以下是插入主表时我想要的行为
1)检查路径表中是否存在路径(通过实体管理器查询,使用路径值作为参数)
2)如果它不存在,插入并获取id(通过实体管理器持久化)
3)将id作为外键值放入主表行,并将其插入主表中.
对于一组域对象,这将发生数千次,对应于主表和其他一些表中的大量行.因此,使用如下的单个事务重复上述步骤:
EntityTransaction t = entityManager.getTransaction();
t.begin();
//perform steps given above, check, and then persist etc..
t.commit();
Run Code Online (Sandbox Code Playgroud)
当我执行第2步时,它会给整个操作带来巨大的性能下降.它正在乞求缓存,因为过了一段时间,该表最多只有10-20k条目,非常罕见的新插入.我试图用Hibernate做到这一点,并且失去了将近2天.
我正在使用Hibernate 4.1,带有JPA注释和ECache.我试图启用查询缓存,甚至在整个插入过程中使用相同的查询对象,如下所示:
Query call = entityManager.createQuery("select pt from NodePath pt " +
"where pt.path = :pathStr)");
call.setHint("org.hibernate.cacheable", true);
call.setParameter("pathStr", pPath);
List<NodePath> paths = call.getResultList();
if(paths.size() > 1)
throw new Exception("path table should have unique paths");
else if (paths.size() == 1){
NodePath path = paths.get(0);
return path.getId();
}
else {//paths null or has zero size
NodePath newPath = new …Run Code Online (Sandbox Code Playgroud) 我一直在尝试使用流畅的nhibernate 1.2和NHibernate 3.1升级到FNH 1.3和NH 3.2的项目,这一切似乎都有效,除了现在我在.List()命令上获得异常.
异常类型和消息是...... NHibernate.Exceptions.GenericADOException无法执行find [SQL:SQL不可用]和内部异常... System.IndexOutOfRangeException索引超出了数组的范围.
我在SQL Server中分析了查询,我认为它是AppFabric缓存和NH 3.2的问题,因为NH生成的查询很好.
代码中的任何内容都没有改变我的FNH和NH引用.
以下是我在C#中的查询...
return ResourceRepository.Query()
.LeftOuterJoin(r => r.ResourceCorpus, () => resourceCorpusAlias)
.LeftOuterJoin(r => r.ResourceType, () => resourceTypeAlias)
.Cachable()
.List();
Run Code Online (Sandbox Code Playgroud)
以下是FNH生成的映射hbm,版本之间没有变化......
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-import="false">
<class xmlns="urn:nhibernate-mapping-2.2" schema="[Reference]" mutable="false" name="MyAssembly.Reference.Resource, MyAssembly.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="`Resource`">
<cache usage="read-only" />
<id name="Id" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" unsaved-value="0">
<column name="Id" />
<generator class="assigned" />
</id>
<bag name="ResourceCorpus" mutable="false">
<cache usage="read-only" />
<key>
<column name="ResourceId" />
</key>
<one-to-many class="MyAssembly.Reference.ResourceCorpus, MyAssembly.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> …Run Code Online (Sandbox Code Playgroud) 我一直在寻找互联网,似乎无法找到我可以下载适用于NHibernate 3.1.0.4000的nhibernate.caches.syscache的v3.1.
我有sys.0ache的3.0.0.4000版本,但是有更新的版本吗?
我们在nHibernate实现中设置了许多缓存区域.为了避免负载均衡的Web服务器出现问题,我希望有效地禁用编辑缓存数据的页面上的缓存.我可以写一个方法来清除我的所有查询缓存,我的类缓存和我的实体缓存很容易.
但我真正想要的是按区域清除缓存.sessionFactory.EvictQueries()将采用region参数,但Evict()和EvictCollection()不会.我真的不想在这里丢弃整个缓存,也不想维护某种笨拙的字典,将类型与缓存区域相关联.nHibernate是否有办法向实体或集合询问其缓存设置是什么?
谢谢
在升级到NHibernate 3.2之前,我使用了以下代码用于Fluent NHibernate:
OracleClientConfiguration configurer = (OracleClientConfiguration.Oracle10.ShowSql().ConnectionString(c =>
c.FromConnectionStringWithKey(ConnectionString.Development))
.DefaultSchema("MySchema")
.UseReflectionOptimizer()
/* Here --> */ .Cache(c =>
c.ProviderClass<SysCacheProvider>()
.UseQueryCache()));
Run Code Online (Sandbox Code Playgroud)
但是,.Cache()NHibernate 3.2中不再使用扩展方法.
我该如何设置缓存提供程序?
编辑:我也尝试过:
.ExposeConfiguration(configuration =>
{
configuration.SetProperty(Environment.UseQueryCache, "true");
configuration.SetProperty(Environment.CacheProvider, "NHibernate.Caches.SysCache.SysCacheProvider, NHibernate.Caches.SysCache2");
});
Run Code Online (Sandbox Code Playgroud)