Home
Help
Register
Log in

Search

 
   Active Threads  

You are here: Home > LLBLGen Pro > Bugs & Issues> error during FetchEntity with PrefetchPaths
 

Pages: 1
Bugs & Issues
error during FetchEntity with PrefetchPaths
Page:1/1 

  Print all messages in this thread  
Poster Message
dvdwouwe
User



Location:
Belgium
Joined on:
24-Jul-2009 19:19:52
Posted:
56 posts
# Posted on: 09-Mar-2010 17:02:49.  
We have a piece of code that fetches an object graph from the database. It has been used already millions of times. Today however, we got an error with the following stack trace.

Code:

msg: Object reference not set to an instance of an object.
Stack:    at SD.LLBLGen.Pro.ORMSupportClasses.PersistenceCore.CalculateHashForEntityBasedOnRelation(IEntityCore entity, IEntityRelation relation, Boolean forPkSide, Boolean& hashRejected)
at SD.LLBLGen.Pro.ORMSupportClasses.PersistenceCore.MergeNormal(IEntityCollectionCore rootEntities, IPrefetchPathElementCore currentElement, Boolean rootEntitiesArePkSide)
at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchPrefetchPath(IEntityCollection2 rootEntities, IRelationPredicateBucket filterBucket, Int64 maxNumberOfItemsToReturn, ISortExpression sortClauses, IPrefetchPath2 prefetchPath, Boolean forceParameterizedPPath)
at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchPrefetchPath(IEntityCollection2 rootEntities, IRelationPredicateBucket filterBucket, Int64 maxNumberOfItemsToReturn, ISortExpression sortClauses, IPrefetchPath2 prefetchPath)
at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchAdditionalPrefetchPath(IPrefetchPath2 prefetchPath, Context contextToUse, IEntity2 fetchedEntity, IRelationPredicateBucket filterToUse)
at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchEntityUsingFilter(IEntity2 entityToFetch, IPrefetchPath2 prefetchPath, Context contextToUse, IRelationPredicateBucket filter, ExcludeIncludeFieldsList excludedIncludedFields)
at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchEntity(IEntity2 entityToFetch, IPrefetchPath2 prefetchPath, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields)
at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchEntity(IEntity2 entityToFetch, IPrefetchPath2 prefetchPath)
at KSZServices.ORM.FetchMessage(Int64 MessageID)


We reviewed our own code and didn't find any errors. Moreover it would seem a bit weird since the code has been running fine for awhile. In addition, we ran the code (after adding extra logging) again on the data that gave problems and this time the code worked just fine.

Any hints on what might have gone wrong here?
  Top
Otis
LLBLGen Pro Team



Location:
The Hague, The Netherlands
Joined on:
17-Aug-2003 18:00:36
Posted:
27585 posts
# Posted on: 09-Mar-2010 17:16:43.  
Could you run the code which crashes with the debug build of the ORMSupportclasses dll ? This debug build is in the runtimelibraries folder. It's the same code built at the same time but with debug switch on, and a pdb file, so we can get a line number with the crash which will make it easier to track down what might went wrong.

Frans Bouma
LLBLGen Pro Lead Developer | Blog | Twitter
 
Top
dvdwouwe
User



Location:
Belgium
Joined on:
24-Jul-2009 19:19:52
Posted:
56 posts
# Posted on: 09-Mar-2010 17:36:23.  
Sadly, we cannot reproduce the issue. This code is running on a production machine. After we encountered the error, we put extra logging in our code, and ran the code again. This time, however, the code executed successfully on the same data.
  Top
MTrinder
Support Team



Location:
London by day, Milton Keynes by night.
Joined on:
08-Oct-2008 17:55:47
Posted:
994 posts
# Posted on: 09-Mar-2010 22:06:15.  
Is the DataAccessAdapter shared across threads at all?

Matt


  Top
dvdwouwe
User



Location:
Belgium
Joined on:
24-Jul-2009 19:19:52
Posted:
56 posts
# Posted on: 10-Mar-2010 10:47:21.  
No, the DataAccessAdapter is not shared acroos threads. We have several threads running in parallel, but each thread allocates its own DataAccessAdapter.
  Top
Walaa
Support Team



Location:
Egypt
Joined on:
21-Aug-2005 16:03:48
Posted:
9817 posts
# Posted on: 10-Mar-2010 10:54:52.  
Neither do you share entities between these threads?

LLBLGen Training
http://www.linkedin.com/in/walaa
 
Top
dvdwouwe
User



Location:
Belgium
Joined on:
24-Jul-2009 19:19:52
Posted:
56 posts
# Posted on: 10-Mar-2010 13:15:31.  
No, the threads work on different sets of tables.
  Top
Walaa
Support Team



Location:
Egypt
Joined on:
21-Aug-2005 16:03:48
Posted:
9817 posts
# Posted on: 10-Mar-2010 17:44:35.  
Could you please specify which runtime library version/build number are you using?

LLBLGen Training
http://www.linkedin.com/in/walaa
 
Top
Otis
LLBLGen Pro Team



Location:
The Hague, The Netherlands
Joined on:
17-Aug-2003 18:00:36
Posted:
27585 posts
# Posted on: 10-Mar-2010 22:45:05.  
The method which crashes, really only allows a nullref to happen if the fields in a relationship are not there or missing, e.g. it's really odd, and likely a shared prefetch path object or relationship shared among threads, but as you say nothing is shared among threads...

It still might be a sharing of elements between threads, so please check that.
Frans Bouma
LLBLGen Pro Lead Developer | Blog | Twitter
 
Top
dvdwouwe
User



Location:
Belgium
Joined on:
24-Jul-2009 19:19:52
Posted:
56 posts
# Posted on: 11-Mar-2010 18:57:36.  
Otis,

It is this code that is running in a WCF service, hosted in an NT service on a Windows 2008 R2 OS that is virtualized.

Code:

        private static PrefetchPath2 RRBISRootNode;
        private static PrefetchPath2 GetRRBISRootNode()
        {
            // Object graph voor RRBISMessage
            // (*) Leaf nodes
            //
            //Citizen
            //    |
            //    +-- StandardAddress
            //    |     |
            //    |     +-- Municipality (*)
            //    |     |
            //    |     +-- Street (*)
            //    |     |
            //    |     +-- Country (*)
            //    |
            //    +-- PlainAddress
            //    |     |
            //    |     +-- Country (*)
            //    |
            //    +-- Location (*)
            //    |
            //    +-- Description (*)
            //    |
            //    +-- ManagerLocation (*)
            //    |
            //    +-- CivilState (*)

            if (RRBISRootNode == null)
            {

                // Level 1
                RRBISRootNode = new PrefetchPath2(EntityType.StgRRBISCitizenEntity);
                IPrefetchPathElement2 StandardAddressNode =
                    RRBISRootNode.Add(StgRRBISCitizenEntity.PrefetchPathStgRRBISStandardAddress);
                IPrefetchPathElement2 PlainAddressNode =
                    RRBISRootNode.Add(StgRRBISCitizenEntity.PrefetchPathStgRRBISPlainAddress);
                RRBISRootNode.Add(StgRRBISCitizenEntity.PrefetchPathStgRRBISLocation);
                RRBISRootNode.Add(StgRRBISCitizenEntity.PrefetchPathStgRRBISDescription);
                RRBISRootNode.Add(StgRRBISCitizenEntity.PrefetchPathStgRRBISManagerLocation);
                RRBISRootNode.Add(StgRRBISCitizenEntity.PrefetchPathStgRRBISCivilState);

                // Level 2
                StandardAddressNode.SubPath.Add(StgRRBISStandardAddressEntity.PrefetchPathStgRRBISCountry);
                StandardAddressNode.SubPath.Add(StgRRBISStandardAddressEntity.PrefetchPathStgRRBISMunicipality);
                StandardAddressNode.SubPath.Add(StgRRBISStandardAddressEntity.PrefetchPathStgRRBISStreet);
                PlainAddressNode.SubPath.Add(StgRRBISPlainAddressEntity.PrefetchPathStgRRBISCountry);
            }
            return RRBISRootNode;
        }
        public static StgRRBISCitizenEntity FetchRRBISMessage(long RRBISCitizenID)
        {
            using (DataAccessAdapter Adapter = ORM.DataAccesAdapterFactory())
            {
                StgRRBISCitizenEntity Citizen = new StgRRBISCitizenEntity(RRBISCitizenID);
                Adapter.FetchEntity(Citizen, GetRRBISRootNode());
                return Citizen;
            }
        }


When we fetched a graph using FetchRRBISMessage we got the error. But the strange thing is after restarting we didn't got it back. The service was running for weeks fine and processed thousands of graphs.

The method that uses the method above is:
Code:

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
    public sealed class ExportXml : IExportXml
    {
    }


The service contract is very simple:
Code:

    [ServiceContract(
        SessionMode = SessionMode.Required,
        Namespace = "http://debouw.be/CrossDB/IExportXml")]
    public interface IExportXml
    {
        [OperationContract]
        ExportXMLFileResult ExportMessages(XmlMessageType XmlMessageType, XmlExportType XmlExportType, string ExportPath);

        [OperationContract]
        XElement ExportMessage(XmlMessageType XmlMessageType, long MessageID);
    }


Now, I m wondering if using a static is the prefered way here?
Because the graph is fetched a lot of times during one service call i used this technique to avoid the cost of building this PrefetchPath again and again.
Or is het much better to use the TLS for this?

Danny


  Top
MTrinder
Support Team



Location:
London by day, Milton Keynes by night.
Joined on:
08-Oct-2008 17:55:47
Posted:
994 posts
# Posted on: 11-Mar-2010 21:16:32.  
Static methods are not inherently thread-safe - it may be worth moving these methods to an actual instance class.

Matt
  Top
Otis
LLBLGen Pro Team



Location:
The Hague, The Netherlands
Joined on:
17-Aug-2003 18:00:36
Posted:
27585 posts
# Posted on: 12-Mar-2010 10:39:14.  
Static variables mean that if the objects they refer to change internally, it's not thread safe. Static methods can be thread safe if they create objects locally and not store them outside themselves (like you do).

A prefetch path contains in a node the data it fetches. So a node is fetched, the data fetched is stored in the EntityCollection in that node and therefore if you share that path among threads, it goes wrong.

So a static method which creates the path for you and returns it to the caller, no problem, as the object is created locally, however storing it and re-using that static object is a problem. So I'd refactor the code in such a way that the path is created every time (which takes almost no time) in a static method.


Frans Bouma
LLBLGen Pro Lead Developer | Blog | Twitter
 
Top
Pages: 1  


Powered by HnD ©2002-2007 Solutions Design
HnD uses LLBLGen Pro

Version: 2.1.12172008 Final.