我有一個奇怪的場景,我有一個引用包含用戶特定行的視圖的表。該視圖具有唯一的行ID,但從未用於引用該項目。相反,唯一值是從客戶端ID,用戶ID和對象鍵的組合派生而來的。過濾器不適用於多對一的參考
public BarMap()
{
Table(DatabaseObject.UserBars);
Id(x => x.Id, "Resource_Id");
Map(x => x.ClientId, "Client_Id");
Map(x => x.UserId, "User_Id");
Map(x => x.Key, "Bar_Key")
.Length(10);
Map(x => x.Name, "Bar_Name")
.Length(255);
我有應用於應基於當前用戶和客戶端方面的WHERE子句中踢類的過濾器。現在我在實踐中看到這些過濾器適用於我直接嘗試檢索條形圖的情況。但是,當我檢索一個名爲Foo的對象,該對象引用一個Bar對象時,將在輔助SELECT調用中跳過這些過濾器。基於上述,你會期望美孚將執行JOIN來滋潤Bar對象
public class FooMap : ClassMap<Foo>
{
public FooMap()
{
Table(DatabaseObject.Foos);
References<Bar>(x => x.Bar, "BarId")
.PropertyRef(x => x.Key)
.Cascade.None()
.Fetch.Join()
.NotFound.Exception();
,但它似乎跳過它,堅持檢索Foo對象。我懷疑二級SELECT呼叫正在發生,因爲NH庫試圖獲取基於密鑰的唯一值的對象(在日誌中
Loader.Loader - SELECT this_.Id as Id12_2_, this_.ClientId as ClientId12_2_, this_.BarId as BarId12_2_, Foo1_.Id as Id13_0_, Foo1_.ClientId as ClientId13_0_, Foo1_.Name as Name13_0_, Bar2_.Resource_Id as Resource1_4_1_, Bar2_.Client_Id as Client7_4_1_, Bar2_.User_Id as User8_4_1_, Bar2_.Bar_Key as Bar9_4_1_, Bar2_.Bar_Name as Bar10_4_1_ FROM Foos this_ inner join FooSchedules Foo1_ on this_.ScheduleId=Foo1_.Id inner join User_Bars Bar2_ on this_.BarId=Bar2_.Bar_Key and (Bar2_.Client_Id = :p0 OR Bar2_.Client_Id IS NULL) and Bar2_.User_Id = :p1 WHERE (Foo1_.ClientId = :p2 OR Foo1_.ClientId IS NULL) and (this_.ClientId = :p3 OR this_.ClientId IS NULL) AND Foo1_.Name = :p4 and Bar2_.Bar_Key = :p5 and Bar2_.Client_Id = :p6 and Bar2_.User_Id = :p7
Loader.Loader - processing result set
Loader.Loader - result set row: 0
我可以看到在這裏它加載的酒吧,但它沒「T滋潤它由於某種原因??
Loader.Loader - result row: EntityKey[Core.Domain.FooSchedule#2929992], EntityKey[Core.Domain.Bar#470090], EntityKey[Core.Domain.Foo#3211664]
Loader.Loader - Initializing object from DataReader: [Core.Domain.FooSchedule#2929992]
Loader.Loader - Initializing object from DataReader: [Core.Domain.Foo#3211664]
Loader.Loader - done processing result set (1 rows)
Loader.Loader - total objects hydrated: 2
Engine.TwoPhaseLoad - resolving associations for [Core.Domain.FooSchedule#2929992]
Engine.Loading.LoadContexts - creating collection wrapper:[Core.Domain.FooSchedule.Foos#2929992]
Engine.TwoPhaseLoad - done materializing entity [Core.Domain.FooSchedule#2929992]
Engine.TwoPhaseLoad - resolving associations for [Core.Domain.Foo#3211664]
Engine.Loading.LoadContexts - creating collection wrapper:[Core.Domain.Foo.Items#3211664]
這裏是它使試圖重新加載酒吧,但不包括使其返回多行/炸掉過濾器....
Loader.Entity.AbstractEntityLoader - Static select for entity Core.Domain.Bar: SELECT Bar0_.Resource_Id as Resource1_4_0_, Bar0_.Client_Id as Client7_4_0_, Bar0_.User_Id as User8_4_0_, Bar0_.Bar_Key as Bar9_4_0_, Bar0_.Bar_Name as Bar10_4_0_ FROM User_Bars Bar0_ WHERE Bar0_.Bar_Key=?
Loader.Loader - loading entity: [Core.Domain.Bar#ABFDBC01]
Engine.QueryParameters - BindParameters(Named:NHibernate.Type.StringType) ABFDBC01 -> [0]
Loader.Loader - SELECT Bar0_.Resource_Id as Resource1_4_0_, Bar0_.Client_Id as Client7_4_0_, Bar0_.User_Id as User8_4_0_, Bar0_.Bar_Key as Bar9_4_0_, Bar0_.Bar_Name as Bar10_4_0_ FROM User_Bars Bar0_ WHERE Bar0_.Bar_Key=:p0
Loader.Loader - processing result set
我很想重構酒吧視圖不存在,但時間限制不會允許它,除非它是絕對必要的。任何想法如何獲得過濾器應用?還是有指導如何做特定於上下文的對象引用?
我發現在JBoss方面Hibernate也可能遭受了potentially related design issue的一些引用。展望代碼NHibernate的源問題似乎圍繞着EntityJoinWalker:
SqlStringBuilder whereCondition = WhereString(Alias, uniqueKey, batchSize)
//include the discriminator and class-level where, but not filters
.Add(persister.FilterFragment(Alias, new CollectionHelper.EmptyMapClass<string, IFilter>()));
如果我將其更改爲這一切工作正常,但我不知道變化的影響是什麼,註釋沒有按」這實際上表明爲什麼過濾器應該被排除。
SqlStringBuilder whereCondition = WhereString(Alias, uniqueKey, batchSize)
.Add(persister.FilterFragment(Alias, enabledFilters));
幫助?!
最初的想法來自於NHForge.org維基使用的上下文過濾器方面感知對象。在關係的情況下,過濾器不適用。不知道如何處理現在關聯一個上下文感知對象。 :S – 2010-09-09 20:52:11