我的域名是一個機場,它包含多個終端,每個終端包含區域等。
由於機場/終端/區域實體的數量非常小,我想:
1.檢索機場時急切地裝載所有的水印。
(使用以下流利的配置:
nHibernate渴望加載 - 奇怪的更新行爲
//eagerly load terminals
mapping.HasMany(x => x.Terminals).Not.LazyLoad()
.Cache.ReadWrite();
)
2.使二級高速緩存,從而使機場對象的所有檢索都打不到的DB。
急切的加載和緩存工作正常,但下面的測試會產生一些奇怪的行爲。
(以下代碼檢索一個機場實體兩次(未擊中DB第二次),和更新它們中的一個。)
[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的:SELECT airport0_.Id如Id36_0_,airport0_.Name如Name36_0_,airport0_.IsDeleted如IsDeleted36_0_ FROM DBO [機場] airport0_ WHERE [email protected]; @ P0 = 1
NHibernate的:SE LECT terminals0_.Airport_id爲Airport4_1_,terminals0_.Id爲Id1_,terminals0_.Id爲Id50_0_,terminals0_.Name爲Name50_0_,terminals0_.IsDeleted爲IsDeleted50_0_,terminals0_.Airport_id爲Airport4_50_0_ FROM dbo。[Terminal] terminals0_ WHERE [email protected] ; @ P0 = 1
NHibernate的:SELECT zones0_.Terminal_id如Terminal4_1_,zones0_.Id如Id1_,zones0_.Id如Id51_0_,zones0_.Name如Name51_0_,zones0_.IsDeleted如IsDeleted51_0_,zones0_.Terminal_id如Terminal4_51_0_ FROM DBO [區] zones0_ WHERE [email protected]; @ P0 = 2
第二選擇
是那些同一機場的實例嗎?假
現在添加終端
NHibernate的:從dbo._uniqueKey選擇next_hi與(UPDLOCK,ROWLOCK)
NHibernate的:更新dbo._uniqueKey設置next_hi = @ P0其中next_hi = @ P1; @ P0 = 17,@ INSERT INTO dbo。[終端](Name,IsDeleted,Airport_id,Id)VALUES(@ p0,@ p1,@ p2,@ p3); @ p0 ='終端被添加到第二機場',p1 = 16
NHibernate:INSERT INTO dbo。 @ 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。[T erminal] 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其中id = @ P1; @ P0 = 1,@ P1 = 16
我的問題是:
1.哪些更新一切奇怪的更新行爲.. 。
2.事實firstAirport和secondAirport是不是同一個對象(也許我失去了一些東西約2級緩存?)
由於事先
的Jhonny
謝謝!這似乎工作。 另外,關於firstAirport!= secondAirport,我的目的是查看一個會話是否更新機場,另一個會話立即看到它(不調用Get())。我現在看到這是一個相當愚蠢的假設。顯然,如果我想查看不同會話對對象所做的更改,我必須再次加載該對象。 – 2010-12-15 14:25:44
也可以使用Merge()查看Ayende的解決方案 - http://ayende.com/Blog/archive/2009/11/08/nhibernate-ndash-cross-session-operations.aspx – 2010-12-15 14:45:21