Why is the Root Entity Type ignored when Prefetching with an Entity?

Posts   
 
    
Posts: 112
Joined: 09-Aug-2004
# Posted on: 02-Oct-2009 19:54:32   

LLBLGen 2.6.9.807 July 27th, 2009


var entity = new LlblgenEntity()
var path = new PrefetchPath2(EntityType.DifferentLlblgenEntity);
path.Add(LlblgenEntity.PrefetchPathSecondEntity);
adapter.FetchEntity(entity, path); //no exception

I would expect that code to throw an exception, but it doesn't. When fetching a collection, it does throw an exception


var entities = new EntityCollection<LlblgenEntity>()
var path = new PrefetchPath2(EntityType.DifferentLlblgenEntity);
path.Add(LlblgenEntity.PrefetchPathSecondEntity);
adapter.FetchEntityCollection(entities, null, path); //exception

Why is this? I would expect the behavior to be consistent. If the FetchEntity method determines the type based off of what is passed in, why can't FetchEntityCollection do the same?

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 03-Oct-2009 03:49:23   

Can't reproduce it with RTL 2.6.9.903, at least with your code. That code doesn't make sense anyway as the prefetch path doesn't have any prefetch path element. The fetch routine don't perform any prefetch routine if prefetchPath.Count = 0 so no exception is hit in any case.

Now, if you put a node on the prefetchPath with invalid root, yes, an exception is hit on fetchEntity but no in fetchEntityCollection (they use different merge routines). In any case, the data is not valid and the prefetchhPath isn't merged in the target object(s).

So, that code doesn't must be written in the first place (is incorrect) simple_smile

David Elizondo | LLBLGen Support Team
Posts: 112
Joined: 09-Aug-2004
# Posted on: 04-Oct-2009 18:24:45   

I updated the code to have a valid path element (sorry, I don't have actual code, I am observing from a team members code).

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 04-Oct-2009 22:05:31   

Yes. As I said before, the fetch/merge routines are different for FetchEntity and FetchEntityCollection. The exception in FetchEntity is due to an inconsistence in the prefetchPath provided.

So, Why don't throw an exception in any case if the prefetchPath provided doesn't match with the entity/collection passed? I don't know really but I think it has something to do with inheritance. For example if you fetch Employees and pass a BoardMemeber rooted prefetch path, it's not exactly the same type but the prefetch is valid.

Anyway, remember that there are may types of errors. One of them is when you write inconsistence code and you obtain unexpected results (no every error should result in an exception). That code is an example. It is about of how the code is written.

David Elizondo | LLBLGen Support Team
Posts: 112
Joined: 09-Aug-2004
# Posted on: 05-Oct-2009 15:08:53   

daelmo wrote:

The exception in FetchEntity is due to an inconsistence in the prefetchPath provided.

That is the problem though, FetchEntity with an invalid Root Entity does not through an exception. I would expect an exception to be thrown though.



var entity = new LlblgenEntity()
var entities = new EntityCollection<LlblgenEntity>()

var path = new PrefetchPath2(EntityType.DifferentLlblgenEntity);
path.Add(LlblgenEntity.PrefetchPathSecondEntity);

adapter.FetchEntity(entity, path); //no exception, makes developer think path is correct. 
adapter.FetchEntityCollection(entities, null, path); //exception about path, confuses developer


When my team member presented me with this code, he thought some type of entity inheritance was going on, however with all the tables listed above there is no inheritance. This behavior is very confusing because the path appears to be valid when fetching an entity, but then throws an exception when fetching a collection. It is invalid code in both cases and it should result in an exception in both cases.

Walaa avatar
Walaa
Support Team
Posts: 14993
Joined: 21-Aug-2005
# Posted on: 05-Oct-2009 16:25:13   

I can't reproduce it. The following code:

            var customer = new CustomersEntity("ALFKI");

            var prefetch = new PrefetchPath2(EntityType.OrdersEntity);
            prefetch.Add(OrdersEntity.PrefetchPathEmployees);

            using(var adapter = new DataAccessAdapter())
            {
                adapter.FetchEntity(customer, prefetch);
            }

Produces the following exception:

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

Stack Trace:

[NullReferenceException: Object reference not set to an instance of an object.] SD.LLBLGen.Pro.ORMSupportClasses.PersistenceCore.DetermineDifferentValuesForParameterizedPPath(IEntityCollectionCore rootEntities, IPrefetchPathCore prefetchPath, IPrefetchPathElementCore currentElement, Hashtable values) +420 SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchPrefetchPath(IEntityCollection2 rootEntities, IRelationPredicateBucket filterBucket, Int64 maxNumberOfItemsToReturn, ISortExpression sortClauses, IPrefetchPath2 prefetchPath, Boolean forceParameterizedPPath) +444 SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchPrefetchPath(IEntityCollection2 rootEntities, IRelationPredicateBucket filterBucket, Int64 maxNumberOfItemsToReturn, ISortExpression sortClauses, IPrefetchPath2 prefetchPath) +27 SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchAdditionalPrefetchPath(IPrefetchPath2 prefetchPath, Context contextToUse, IEntity2 fetchedEntity, IRelationPredicateBucket filterToUse) +122 SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchEntityUsingFilter(IEntity2 entityToFetch, IPrefetchPath2 prefetchPath, Context contextToUse, IRelationPredicateBucket filter, ExcludeIncludeFieldsList excludedIncludedFields) +650 SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchEntity(IEntity2 entityToFetch, IPrefetchPath2 prefetchPath, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) +130 SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchEntity(IEntity2 entityToFetch, IPrefetchPath2 prefetchPath) +34 ...

Posts: 112
Joined: 09-Aug-2004
# Posted on: 05-Oct-2009 19:54:53   

The path elements should be correct but the root should be incorrect.


            var customer = new CustomersEntity("ALFKI");

            var prefetch = new PrefetchPath2(EntityType.OrdersEntity); //incorrect
            prefetch.Add(CustomerEntity.PrefetchPathOrders); //correct

            using(var adapter = new DataAccessAdapter())
            {
                adapter.FetchEntity(customer, prefetch);
            }

Walaa avatar
Walaa
Support Team
Posts: 14993
Joined: 21-Aug-2005
# Posted on: 06-Oct-2009 12:10:49   

This also gives another exception:

The prefetch path element at index 0 in the passed in prefetch path for root entity type 7 is meant for root entity type 0 which isn't a subtype of 7. This means that you've added a prefetch path node to a Path of an unrelated entity, for example adding OrderDetailsEntity.PrefetchPathProduct to a prefetch path for CustomerEntity. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.ApplicationException: The prefetch path element at index 0 in the passed in prefetch path for root entity type 7 is meant for root entity type 0 which isn't a subtype of 7. This means that you've added a prefetch path node to a Path of an unrelated entity, for example adding OrderDetailsEntity.PrefetchPathProduct to a prefetch path for CustomerEntity.

Stack Trace:

[ApplicationException: The prefetch path element at index 0 in the passed in prefetch path for root entity type 7 is meant for root entity type 0 which isn't a subtype of 7. This means that you've added a prefetch path node to a Path of an unrelated entity, for example adding OrderDetailsEntity.PrefetchPathProduct to a prefetch path for CustomerEntity.] SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchPrefetchPath(IEntityCollection2 rootEntities, IRelationPredicateBucket filterBucket, Int64 maxNumberOfItemsToReturn, ISortExpression sortClauses, IPrefetchPath2 prefetchPath, Boolean forceParameterizedPPath) +1294 SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchPrefetchPath(IEntityCollection2 rootEntities, IRelationPredicateBucket filterBucket, Int64 maxNumberOfItemsToReturn, ISortExpression sortClauses, IPrefetchPath2 prefetchPath) +27 SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchAdditionalPrefetchPath(IPrefetchPath2 prefetchPath, Context contextToUse, IEntity2 fetchedEntity, IRelationPredicateBucket filterToUse) +122 SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchEntityUsingFilter(IEntity2 entityToFetch, IPrefetchPath2 prefetchPath, Context contextToUse, IRelationPredicateBucket filter, ExcludeIncludeFieldsList excludedIncludedFields) +651 SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchEntity(IEntity2 entityToFetch, IPrefetchPath2 prefetchPath, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields) +130 SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchEntity(IEntity2 entityToFetch, IPrefetchPath2 prefetchPath) +34