Exception on new Entity with PK and PrefetchPath

Posts   
 
    
jaskey avatar
jaskey
User
Posts: 23
Joined: 09-Jul-2006
# Posted on: 07-Sep-2007 07:32:11   

I am getting an exception when creating an entity with a single int PK and a PrefetchPath in the constructor... the natch is that the PK value in this case does not exist in the database. I figured I would just get an 'IsNew = true' entity tho.

My exception is a {"Key cannot be null.\r\nParameter name: key"} and my StackTrace is...

LLBL v2.5 Self Servicing

at System.Collections.Hashtable.Insert(Object key, Object nvalue, Boolean add) at System.Collections.Hashtable.set_Item(Object key, Object value) at SD.LLBLGen.Pro.ORMSupportClasses.DaoBase.DetermineDifferentValuesForParameterizedPPath(IEntityCollection rootEntities, IPrefetchPath prefetchPath, IPrefetchPathElement currentElement, Int32& amountRootEntitiesUsable) at SD.LLBLGen.Pro.ORMSupportClasses.DaoBase.FetchPrefetchPath(IEntityCollection rootEntities, IPredicate filter, IRelationCollection relations, Int64 maxNumberOfItemsToReturn, ISortExpression sortClauses, IPrefetchPath prefetchPath, ITransaction containingTransaction, Boolean forceParameterizedPPath) at SD.LLBLGen.Pro.ORMSupportClasses.DaoBase.PerformFetchEntityAction(IEntity entityToFetch, ITransaction containingTransaction, IPredicateExpression selectFilter, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) at SD.LLBLGen.Pro.ORMSupportClasses.DaoBase.FetchExisting(IEntity entityToFetch, ITransaction containingTransaction, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) at IPSND.DAL.EntityClasses.GameEntity.Fetch(Int32 ipdbid, IPrefetchPath prefetchPathToUse, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) in C:\Documents and Settings\jess\My Documents\Visual Studio 2005\Projects\IPSND.DAL\EntityClasses\GameEntity.cs:line 1625 at IPSND.DAL.EntityClasses.GameEntity.InitClassFetch(Int32 ipdbid, IValidator validator, IPrefetchPath prefetchPathToUse) in C:\Documents and Settings\jess\My Documents\Visual Studio 2005\Projects\IPSND.DAL\EntityClasses\GameEntity.cs:line 1395 at IPSND.DAL.EntityClasses.GameEntity..ctor(Int32 ipdbid, IPrefetchPath prefetchPathToUse) in C:\Documents and Settings\jess\My Documents\Visual Studio 2005\Projects\IPSND.DAL\EntityClasses\GameEntity.cs:line 134 at GameControl.SetGame(Int32 id) in c:\Documents and Settings\jess\My Documents\Visual Studio 2005\WebSites\IPSD\Controls\GameControl.ascx.cs:line 57 at View.Page_Load(Object sender, EventArgs e) in c:\Documents and Settings\jess\My Documents\Visual Studio 2005\WebSites\IPSD\View.aspx.cs:line 29 at System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) at System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) at System.Web.UI.Control.OnLoad(EventArgs e) at System.Web.UI.Control.LoadRecursive() at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

The more interesting part is that I have about 7 items in my prefetch path. I can narrow it down to one specific path that relates the root entity to the path destination... this is a simple Many to 1 from the entity table

Root Entity is Game PrefetchPathManufacturer is used ManufacturerId is in the game table

As I mentioned at the top, the real issue seems to be only when the PK int I supply in the constructor does not exist for the root entity. I don't think this should be causing an exception tho... should it?

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 07-Sep-2007 09:22:35   

Would you please post the corresponding code snippet?

In SelfServicing, supplying the PK in the constructor makes the framework attempt to fetch the entity from the database.

jaskey avatar
jaskey
User
Posts: 23
Joined: 09-Jul-2006
# Posted on: 08-Sep-2007 01:46:17   

Here is the code snippet...

    IPrefetchPath prefetchPath = new PrefetchPath((int)EntityType.GameEntity);
    prefetchPath.Add(GameEntity.PrefetchPathSerial);
    prefetchPath.Add(GameEntity.PrefetchPathGamePartCollectionViaSerial);
    prefetchPath.Add(GameEntity.PrefetchPathCountryCollectionViaSerial);
    prefetchPath.Add(GameEntity.PrefetchPathGameSerialMask);
    prefetchPath.Add(GameEntity.PrefetchPathManufacturer);
    prefetchPath.Add(GameEntity.PrefetchPathMpu);
    prefetchPath.Add(GameEntity.PrefetchPathConditionCollectionViaSerial);
    prefetchPath.Add(GameEntity.PrefetchPathSerialStatusCollectionViaSerial);
    prefetchPath.Add(GameEntity.PrefetchPathSerialType);
    GameEntity _game = new GameEntity(id, prefetchPath);

After looking at the documentation it seems that I should technically be doing this a little more efficiently but I didn't think that this should cause an exception?

I just upgraded from 1.0 and this code worked fine there. The big difference that I have been fixing bugs around is the 'nullability' feature of 2.0+

In the end, I can understand why this would get confusing if the PK id didn't exist but again, I guess it wasn't a problem in 1.0 SelfServicing. Since my id can be any arbitrary int passed in via the QueryString, I have just been instantiating the entity and then checking the IsNew property to see if it existed, then dealing with the behavior at that point.

For now, Im just catch{}ing the exception but Im curious as to the buried change in 2.0+ if anyone has any reflection.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 10-Sep-2007 14:28:52   

Will look into it.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 11-Sep-2007 10:53:03   

I can't really reproduce it with a test:


[Test]
public void FetchNonExistingEntityWithPrefetchPath()
{
    PrefetchPath path = new PrefetchPath((int)EntityType.OrderEntity);
    path.Add(OrderEntity.PrefetchPathCustomers);
    path.Add(OrderEntity.PrefetchPathOrderDetails);

    OrderEntity o = new OrderEntity(13131313, path);
    Assert.IsTrue(o.IsNew);
    Assert.AreEqual(EntityState.New, o.Fields.State);
}

(v2.0)

However, in v2.5, I CAN reproduce it. Will try to fix this.

(edit) Fixed in next build.

Frans Bouma | Lead developer LLBLGen Pro
jaskey avatar
jaskey
User
Posts: 23
Joined: 09-Jul-2006
# Posted on: 12-Sep-2007 08:07:28   

Excellent... thank you as always. :-)