Enabling EntityCache and QueryCache

--HG--
branch : NH3
This commit is contained in:
Sebastien Ros 2012-07-12 11:18:27 -07:00
parent 6a14aa405c
commit 027e7b0301
8 changed files with 98 additions and 12 deletions

Binary file not shown.

View File

@ -21,7 +21,7 @@ namespace Orchard.Tests {
//var persistenceModel = AutoMap.Source(new Types(types))
// .Alterations(alt => AddAlterations(alt, types))
// .Conventions.AddFromAssemblyOf<DataModule>();
var persistenceModel = AbstractDataServicesProvider.CreatePersistenceModel(types.Select(t => new RecordBlueprint { TableName = "Test_" + t.Name, Type = t }));
var persistenceModel = AbstractDataServicesProvider.CreatePersistenceModel(types.Select(t => new RecordBlueprint { TableName = "Test_" + t.Name, Type = t }).ToList());
var persistenceConfigurer = new SqlCeDataServicesProvider(fileName).GetPersistenceConfigurer(true/*createDatabase*/);
((MsSqlCeConfiguration)persistenceConfigurer).ShowSql();

View File

@ -158,6 +158,11 @@
<bindingRedirect oldVersion="2.0.0.0" newVersion="1.0.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="NHibernate" publicKeyToken="aa95f207798dfdb4" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.3.1.4000" newVersion="3.3.1.4000" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@ -76,7 +76,7 @@ namespace Orchard.ContentManagement {
IQueryOver<ContentItemVersionRecord, ContentItemVersionRecord> BindItemVersionQueryOver() {
if (_itemVersionQueryOver == null) {
_itemVersionQueryOver = BindSession().QueryOver<ContentItemVersionRecord>();
//_itemVersionQueryOver.Cacheable();
_itemVersionQueryOver.Cacheable();
}
return _itemVersionQueryOver;
}

View File

@ -0,0 +1,25 @@
using System.Collections.Generic;
using System.Linq;
using FluentNHibernate.Conventions;
using FluentNHibernate.Conventions.AcceptanceCriteria;
using FluentNHibernate.Conventions.Inspections;
using FluentNHibernate.Conventions.Instances;
using Orchard.Environment.ShellBuilders.Models;
namespace Orchard.Data.Conventions {
public class CacheConvention : IClassConvention, IConventionAcceptance<IClassInspector> {
private readonly IEnumerable<RecordBlueprint> _descriptors;
public CacheConvention(IEnumerable<RecordBlueprint> descriptors) {
_descriptors = descriptors;
}
public void Apply(IClassInstance instance) {
instance.Cache.ReadWrite();
}
public void Accept(IAcceptanceCriteria<IClassInspector> criteria) {
criteria.Expect(x => _descriptors.Any(d => d.Type.Name == x.EntityType.Name));
}
}
}

View File

@ -59,7 +59,7 @@ namespace Orchard.Data.Migration.Generator {
//var features = dependencies.Select(name => new ShellFeature {Name = name}).Union(new[] {new ShellFeature {Name = feature}, new ShellFeature {Name = "Orchard.Framework"}});
var parameters = _sessionFactoryHolder.GetSessionFactoryParameters();
parameters.RecordDescriptors = shellBlueprint.Records;
parameters.RecordDescriptors = shellBlueprint.Records.ToList();
var configuration = _dataServicesProviderFactory
.CreateProvider(parameters)

View File

@ -8,8 +8,12 @@ using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using FluentNHibernate.Conventions.Helpers;
using FluentNHibernate.Diagnostics;
using NHibernate.Cache;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Engine;
using NHibernate.Event;
using NHibernate.Event.Default;
using NHibernate.Persister.Entity;
using Orchard.ContentManagement.Records;
using Orchard.Data.Conventions;
using Orchard.Environment.ShellBuilders.Models;
@ -21,28 +25,32 @@ namespace Orchard.Data.Providers {
public Configuration BuildConfiguration(SessionFactoryParameters parameters) {
var database = GetPersistenceConfigurer(parameters.CreateDatabase);
var persistenceModel = CreatePersistenceModel(parameters.RecordDescriptors);
var persistenceModel = CreatePersistenceModel(parameters.RecordDescriptors.ToList());
return Fluently.Configure()
.Database(database)
.Mappings(m => m.AutoMappings.Add(persistenceModel))
.ExposeConfiguration(cfg => cfg.EventListeners.LoadEventListeners = new ILoadEventListener[] { new OrchardLoadEventListener() })
.BuildConfiguration()
//.Cache(c => {
// c.UseQueryCache = true;
// c.Provider<HashtableCacheProvider>();
// })
//.EntityCache<ContentItemRecord>(x => x.Strategy = EntityCacheUsage.ReadWrite)
//.EntityCache<ContentItemVersionRecord>(x => x.Strategy = EntityCacheUsage.ReadWrite)
.Cache(c => {
c.Provider<NHibernate.Caches.SysCache2.SysCacheProvider>();
c.UseQueryCache = true;
})
;
}
public static AutoPersistenceModel CreatePersistenceModel(IEnumerable<RecordBlueprint> recordDescriptors) {
public static AutoPersistenceModel CreatePersistenceModel(ICollection<RecordBlueprint> recordDescriptors) {
if(recordDescriptors == null) {
throw new ArgumentNullException("recordDescriptors");
}
return AutoMap.Source(new TypeSource(recordDescriptors))
// Ensure that namespaces of types are never auto-imported, so that
// identical type names from different namespaces can be mapped without ambiguity
.Conventions.Setup(x => x.Add(AutoImport.Never()))
.Conventions.Add(new RecordTableNameConvention(recordDescriptors))
.Conventions.Add(new CacheConvention(recordDescriptors))
.Alterations(alt => {
foreach (var recordAssembly in recordDescriptors.Select(x => x.Type.Assembly).Distinct()) {
alt.Add(new AutoMappingOverrideAlteration(recordAssembly));
@ -68,5 +76,49 @@ namespace Orchard.Data.Providers {
throw new NotImplementedException();
}
}
class OrchardLoadEventListener : DefaultLoadEventListener, ILoadEventListener {
public new void OnLoad(LoadEvent @event, LoadType loadType) {
var source = (ISessionImplementor)@event.Session;
IEntityPersister entityPersister;
if (@event.InstanceToLoad != null) {
entityPersister = source.GetEntityPersister(null, @event.InstanceToLoad);
@event.EntityClassName = @event.InstanceToLoad.GetType().FullName;
}
else
entityPersister = source.Factory.GetEntityPersister(@event.EntityClassName);
if (entityPersister == null)
throw new HibernateException("Unable to locate persister: " + @event.EntityClassName);
//a hack to handle unused ContentPartRecord proxies on ContentItemRecord or ContentItemVersionRecord.
//I don't know why it actually works, or how to do it right
//if (!entityPersister.IdentifierType.IsComponentType)
//{
// Type returnedClass = entityPersister.IdentifierType.ReturnedClass;
// if (returnedClass != null && !returnedClass.IsInstanceOfType(@event.EntityId))
// throw new TypeMismatchException(string.Concat(new object[4]
// {
// (object) "Provided id of the wrong type. Expected: ",
// (object) returnedClass,
// (object) ", got ",
// (object) @event.EntityId.GetType()
// }));
//}
var keyToLoad = new EntityKey(@event.EntityId, entityPersister, source.EntityMode);
if (loadType.IsNakedEntityReturned) {
@event.Result = Load(@event, entityPersister, keyToLoad, loadType);
}
else if (@event.LockMode == LockMode.None) {
@event.Result = ProxyOrLoad(@event, entityPersister, keyToLoad, loadType);
}
else {
@event.Result = LockAndLoad(@event, entityPersister, keyToLoad, loadType, source);
}
}
}
}
}

View File

@ -93,6 +93,9 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\lib\nhibernate\NHibernate.dll</HintPath>
</Reference>
<Reference Include="NHibernate.Caches.SysCache2">
<HintPath>..\..\lib\nhibernate\NHibernate.Caches.SysCache2.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
@ -161,6 +164,7 @@
<Compile Include="ContentManagement\QueryHints.cs" />
<Compile Include="ContentManagement\Utilities\ComputedField.cs" />
<Compile Include="Data\Conventions\AggregateAttribute.cs" />
<Compile Include="Data\Conventions\CacheConvention.cs" />
<Compile Include="Data\Migration\AutomaticDataMigrations.cs" />
<Compile Include="DisplayManagement\Descriptors\PlacementInfo.cs" />
<Compile Include="DisplayManagement\Descriptors\ResourceBindingStrategy\StylesheetBindingStrategy.cs" />