мой домен - это аэропорт, который содержит несколько терминалов, и каждый терминал содержит зоны и т. д.
поскольку количество объектов аэропорта / терминала / зоны очень мало, я хотел бы:
1. загрузить всю иерархию с нетерпением при поиске аэропорта.
(с использованием следующей быстрой конфигурации:
//eagerly load terminals
mapping.HasMany(x => x.Terminals).Not.LazyLoad()
.Cache.ReadWrite();
)
2. Включите кэширование 2-го уровня, чтобы все извлечения объекта аэропорта не попадали в БД.
жадная загрузка и кеширование работают нормально, но следующий тест вызывает странное поведение.
(следующий код дважды извлекает объект аэропорта (второй раз не попадает в БД) и обновляет один из них.)
[TestMethod]
public void TestSecondLevelCache()
{
Airport firstAirport = null, secondAirport = null;
Console.WriteLine("first select");
using (ISession session = this.SessionFactory.OpenSession())
{
using (ITransaction transaction = session.BeginTransaction())
{
//the idea here is to see whether there are two calls to DB here. check the sql output
AirportDAO dao = new AirportDAO(session);
firstAirport = dao.GetAirport();
transaction.Commit();
}
}
Console.WriteLine("second select");
using (ISession session = this.SessionFactory.OpenSession())
{
using (ITransaction transaction = session.BeginTransaction())
{
//the idea here is to see whether there are two calls to DB here. check the sql output
AirportDAO dao = new AirportDAO(session);
secondAirport = dao.GetAirport();
transaction.Commit();
}
}
Console.WriteLine("Are those the same airport instance? " + firstAirport.Equals(secondAirport));
Console.WriteLine("now adding a terminal");
using (ISession session = this.SessionFactory.OpenSession())
{
using (ITransaction transaction = session.BeginTransaction())
{
secondAirport.Terminals.Add(new Terminal() { Name = "terminal added to second airport", Zones = new List<Zone>() });
session.Update(secondAirport);
transaction.Commit();
}
}
//this Assert fails, since firstAirport != secondAirport
Assert.IsNotNull(firstAirport.Terminals.FirstOrDefault(t => t.Name.Contains("second airport")));
}
увидеть результат:
first select
NHibernate: SELECT airport0_.Id as Id36_0_, airport0_.Name as Name36_0_, airport0_.IsDeleted as IsDeleted36_0_ FROM dbo.[Airport] airport0_ WHERE airport0_.Id=@p0;@p0 = 1
NHibernate: SELECT terminals0_.Airport_id as Airport4, terminals0_.Id as Id1_, terminals0_.Id as Id50_0_, terminals0_.Name as Name50_0_, terminals0_.IsDeleted as IsDeleted50_0_, terminals0_.Airport_id as Airport4_50_0_ FROM dbo.[Terminal] terminals0_ WHERE terminals0_.Airport_id=@p0;@p0 = 1//eagerly load terminals mapping.HasMany(x => x.Terminals).Not.LazyLoad() .Cache.ReadWrite();
NHibernate: SELECT zones0_.Terminal_id as Terminal4, zones0_.Id as Id1_, zones0_.Id as Id51_0_, zones0_.Name as Name51_0_, zones0_.IsDeleted as IsDeleted51_0_, zones0_.Terminal_id as Terminal4_51_0_ FROM dbo.[Zone] zones0_ WHERE zones0_.Terminal_id=@p0;@p0 = 2//eagerly load terminals mapping.HasMany(x => x.Terminals).Not.LazyLoad() .Cache.ReadWrite();
second select
Are those the same airport instance? False
now adding a terminal
NHibernate: select next_hi from dbo._uniqueKey with (updlock, rowlock)
NHibernate: update dbo._uniqueKey set next_hi = @p0 where next_hi = @p1;@p0 = 17, @p1 = 16
NHibernate: INSERT INTO dbo.[Terminal] (Name, IsDeleted, Airport_id, Id) VALUES (@p0, @p1, @p2, @p3);@p0 = 'terminal added to second airport', @p1 = False, @p2 = NULL, @p3 = 16
NHibernate: UPDATE dbo.[Airport] SET Name = @p0, IsDeleted = @p1 WHERE Id = @p2;@p0 = 'test airport', @p1 = False, @p2 = 1
NHibernate: UPDATE dbo.[Terminal] SET Name = @p0, IsDeleted = @p1, Airport_id = @p2 WHERE Id = @p3;@p0 = 'test terminal', @p1 = False, @p2 = 1, @p3 = 2
NHibernate: UPDATE dbo.[Zone] SET Name = @p0, IsDeleted = @p1, Terminal_id = @p2 WHERE Id = @p3;@p0 = 'test zone', @p1 = False, @p2 = 2, @p3 = 3
NHibernate: UPDATE dbo.[Terminal] SET Airport_id = @p0 WHERE Id = @p1;@p0 = 1, @p1 = 16
my problems are:
1. the strange update behaviour which updates everything...
2. the fact that firstAirport and secondAirport are not the same object (maybe I'm missing something about 2nd level cache?)
thanks in advance,
Jhonny