私のドメインは、いくつかのターミナルを含む空港であり、各ターミナルにはゾーンなどが含まれています。
空港/ターミナル/ゾーンのエンティティの数が非常に少ないため、次のことを行いたいと思い
ます。1. 空港を取得するときに、すべての階層を熱心にロードします。
(次の流暢な構成を使用:
//eagerly load terminals
mapping.HasMany(x => x.Terminals).Not.LazyLoad()
.Cache.ReadWrite();
)
2. 第 2 レベルのキャッシュを有効にして、空港オブジェクトのすべての取得が DB にヒットしないようにします。
熱心な読み込みとキャッシングは正常に機能しますが、次のテストでは奇妙な動作が発生します。
(次のコードは空港エンティティを 2 回取得し (2 回目は DB にヒットしません)、そのうちの 1 つを更新します。)
[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")));
}
結果の出力を参照してください。
最初に
NHibernate を選択します: Id36_0_ として airport0_.Id を
選択します。 Terminals0_.Id は Id1_、terminal0_.Id は Id50_0_、terminal0_.Name は Name50_0_、terminal0_.IsDeleted は IsDeleted50_0_、terminal0_.Airport_id は Airport4_50_0_ FROM dbo.[ターミナル] WHEREterminal0_.Airport_id=@p0;@p0 = 1
NHibernate: Zone0_.Terminal_id を Terminal4_1_ として、zones0_.Id を Id1_ として、zones0_.Id を Id51_0_ として、zones0_.Name を Name51_0_ として、zones0_.IsDeleted を IsDeleted51_0_ として、zone0_.Terminal_id を Terminal4_51_0_ として選択します。 ;@p0 = 2
秒の選択
それらは同じ空港インスタンスですか?False
ターミナル
を 追加
する
.[Terminal] (Name, IsDeleted, Airport_id, Id) VALUES (@p0, @p1, @p2, @p3);@p0 = '2 番目の空港に追加されたターミナル', @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.[ターミナル] SET Airport_id = @p0 WHERE Id = @p1;@p0 = 1, @p1 = 16
私の問題は次のとおりです:
1. すべてを更新する奇妙な更新動作...
2. firstAirport と secondAirport が同じオブジェクトではないという事実 (おそらく、第 2 レベルのキャッシュについて何かが欠けているのでしょうか?)
事前に感謝します、
Jhonny