Inheritance bug?

Posts   
 
    
TomV
User
Posts: 76
Joined: 31-Jan-2008
# Posted on: 16-Jul-2009 13:27:03   

Hi,

LLBLGenPro 2.6Final, released on August 18th, 2008 Runtime: 26/06/2009

I have 2 inheritance trees in my llblgenpro project. As attachment you may find screenshots of both of them.

For resources (llblgenpro1.jpg) everything is OK, but I have a problem with the devices inheritance (llblgenpro2.jpg).

Here follows a sample of good code that does what it should do sunglasses


         DataServer = new GalantisService();

         EntityCollection<DeviceEntity> devices = new EntityCollection<DeviceEntity>(new DeviceEntityFactory());
         DataServer.Adapter.FetchEntityCollection(devices, null);

         EntityCollection<EmployeeEntity> emp = new EntityCollection<EmployeeEntity>();
         DataServer.Adapter.FetchEntityCollection(emp, null);

         EntityCollection<VisitorEntity> vis = new EntityCollection<VisitorEntity>();
         DataServer.Adapter.FetchEntityCollection(vis, null);

         EntityCollection<PersonEntity> per = new EntityCollection<PersonEntity>(new PersonEntityFactory());
         DataServer.Adapter.FetchEntityCollection(per, null);

         Console.WriteLine(String.Format("emp {0} - vis {1} - person {2}", emp.Count, vis.Count, per.Count));


the person count equals the count of employee and visitor together. the problem is with the devices hierarchy, first you see the executed code, below the error I receive


         EntityCollection<DataDeviceEntity> presence = new EntityCollection<DataDeviceEntity>(new DataDeviceEntityFactory());
         DataServer.Adapter.FetchEntityCollection(presence, null);


Error: entityToAdd isn't of the right type

When I attach a IRelationPredicateBucket saying that I only want entities with the discriminator EM3xx and RegistrationPoint, things work ok. But this is not how it should be cry


         IRelationPredicateBucket filter = new RelationPredicateBucket();
         filter.PredicateExpression.Add(DataDeviceFields.Discriminator == DeviceDiscriminator.RegistrationPoint.ToString()
            | DataDeviceFields.Discriminator == DeviceDiscriminator.EM3xx.ToString());

         EntityCollection<DataDeviceEntity> presence = new EntityCollection<DataDeviceEntity>(new DataDeviceEntityFactory());
         DataServer.Adapter.FetchEntityCollection(presence, filter);


MTrinder
User
Posts: 1461
Joined: 08-Oct-2008
# Posted on: 16-Jul-2009 21:32:39   

Hi

Please could you post the complete stack trace of the exception - this will give us a chance to see the code path that the error is coming from.

Thanks

Matt

TomV
User
Posts: 76
Joined: 31-Jan-2008
# Posted on: 17-Jul-2009 07:37:49   

Hi Matt,

In attachment you find screenshot of debug error window, below the complete error information, stacktrace inclusive. Hope that this helps. If you need anything else, just let me know.

System.ArgumentException Message: entityToAdd isn't of the right type ParamName: null Source: SD.LLBLGen.Pro.ORMSupportClasses.NET20 StackTrace:

bij SD.LLBLGen.Pro.ORMSupportClasses.EntityCollectionBase2`1.SD.LLBLGen.Pro.ORMSupportClasses.IEntityCollection2.Add(IEntity2 entityToAdd) bij SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.ExecuteMultiRowRetrievalQuery(IRetrievalQuery queryToExecute, IEntityFactory2 entityFactory, IEntityCollection2 collectionToFill, IFieldPersistenceInfo[] fieldsPersistenceInfo, Boolean allowDuplicates, IEntityFields2 fieldsUsedForQuery) bij SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchEntityCollectionInternal(IEntityCollection2 collectionToFill, IRelationPredicateBucket& filterBucket, Int32 maxNumberOfItemsToReturn, ISortExpression sortClauses, ExcludeIncludeFieldsList excludedIncludedFields, Int32 pageNumber, Int32 pageSize) bij SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchEntityCollection(IEntityCollection2 collectionToFill, IRelationPredicateBucket filterBucket, Int32 maxNumberOfItemsToReturn, ISortExpression sortClauses, IPrefetchPath2 prefetchPath, ExcludeIncludeFieldsList excludedIncludedFields, Int32 pageNumber, Int32 pageSize) bij SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchEntityCollection(IEntityCollection2 collectionToFill, IRelationPredicateBucket filterBucket) bij GalantisTestSolution.SmallThings.SmallThings_Load(Object sender, EventArgs e) in C:\Users\tom.vergotte\Documents\Visual Studio 2008\Projects\GalantisTestSolution\GalantisTestSolution\SmallThings.cs:regel 52 bij System.Windows.Forms.Form.OnLoad(EventArgs e) bij System.Windows.Forms.Form.OnCreateControl() bij System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible) bij System.Windows.Forms.Control.CreateControl() bij System.Windows.Forms.Control.WmShowWindow(Message& m) bij System.Windows.Forms.Control.WndProc(Message& m) bij System.Windows.Forms.ScrollableControl.WndProc(Message& m) bij System.Windows.Forms.ContainerControl.WndProc(Message& m) bij System.Windows.Forms.Form.WmShowWindow(Message& m) bij System.Windows.Forms.Form.WndProc(Message& m) bij System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) bij System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) bij System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) bij System.Windows.Forms.SafeNativeMethods.ShowWindow(HandleRef hWnd, Int32 nCmdShow) bij System.Windows.Forms.Control.SetVisibleCore(Boolean value) bij System.Windows.Forms.Form.SetVisibleCore(Boolean value) bij System.Windows.Forms.Control.set_Visible(Boolean value) bij System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) bij System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) bij System.Windows.Forms.Application.Run(Form mainForm) bij GalantisTestSolution.Program.Main() in C:\Users\tom.vergotte\Documents\Visual Studio 2008\Projects\GalantisTestSolution\GalantisTestSolution\Program.cs:regel 18 bij System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args) bij System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) bij Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() bij System.Threading.ThreadHelper.ThreadStart_Context(Object state) bij System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) bij System.Threading.ThreadHelper.ThreadStart()

Kind regards, TomV

Walaa avatar
Walaa
Support Team
Posts: 14946
Joined: 21-Aug-2005
# Posted on: 17-Jul-2009 10:29:49   

EntityCollection<DataDeviceEntity> presence = new EntityCollection<DataDeviceEntity>(new DataDeviceEntityFactory()); DataServer.Adapter.FetchEntityCollection(presence, null);

Error: entityToAdd isn't of the right type

When I attach a IRelationPredicateBucket saying that I only want entities with the discriminator EM3xx and RegistrationPoint, things work ok. But this is not how it should be

The fetch is polymorphic, i.e. fetches all entities of the specified types (a child is also of the parent's type). But yet you specify a limiting entityFactory in the CTor of the collection.

If you want to limit the fetched entities to a specific type you should use enity type filtering.

And so your collection should be defined without the factory as follows:

EntityCollection<DataDeviceEntity> presence = new EntityCollection<DataDeviceEntity>();
TomV
User
Posts: 76
Joined: 31-Jan-2008
# Posted on: 17-Jul-2009 10:35:52   

Hi Walaa,

I need to use the DataDeviceFactory because the DataDeviceEntity is 'abstract'. The whole hierarchy is available as screenshot in my first post.

With my Resource hierarchy everything works just fine, it's the DevicesHierarchy that causes some problems. This is caused by bug of LLBLGen or by bug of me sunglasses

The following lines work just fine: Please not that PersonEntity is also 'abstract'

EntityCollection<PersonEntity> per = new EntityCollection<PersonEntity>(new PersonEntityFactory()); DataServer.Adapter.FetchEntityCollection(per, null);

Regards, TomV

Walaa avatar
Walaa
Support Team
Posts: 14946
Joined: 21-Aug-2005
# Posted on: 17-Jul-2009 11:44:24   

I see your problem, but I can't reprodcue it, similar to your resource hierarchy everything is working over here.

Would you please attach a repro solution of your dataDevice hierarchy?

TomV
User
Posts: 76
Joined: 31-Jan-2008
# Posted on: 17-Jul-2009 11:46:35   

Hi Walaa,

I will try to create it today and will start new post in private forum with link to this thread.

Regards, TomV

TomV
User
Posts: 76
Joined: 31-Jan-2008
# Posted on: 17-Jul-2009 12:25:26   

Hi Walaa,

  • I created a new database with only the Devices table.
  • I deleted everything from my LLBLGenPro project except Device, DataDevice and RegistrationPoint. I created a new type 'Test' derived from Device.
  • I added 3 rows in my devices table. (Discriminators: RegistrationPoint, Test, Test); I created a new solution and fetched the collection

Off course everything works just fine like for my resources/persons example.

So I think there is something strange in my solution file.

The only option I see is remove DataDeviceEntity and derived classes and restart allover for that inheritance branch.

Do you have any other suggestion what I can do to correct this inheritance issue?

Kind regards, TomV

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 18-Jul-2009 05:15:10   

Tom,

Leave the LGP just like it is. Just prepare a tiny repro-solution. Send the DB script with some records to test, the LGP, and a console app that reproduces the problem with that hierarchy.

David Elizondo | LLBLGen Support Team
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 20-Jul-2009 18:25:10   

The exception is thrown because the type of the element to add to the collection is not implementing the generic type of the collection.

So in your query:

EntityCollection<DataDeviceEntity> presence = new EntityCollection<DataDeviceEntity>(new DataDeviceEntityFactory());
         DataServer.Adapter.FetchEntityCollection(presence, null);

you should get all datadevice entities and all subtypes. When you run the above query, please check the generated SQL to see if it indeed produces the proper query, i.e. with the correct discriminator filter. Could you check that for me please?

Frans Bouma | Lead developer LLBLGen Pro
TomV
User
Posts: 76
Joined: 31-Jan-2008
# Posted on: 22-Jul-2009 07:44:41   

Hi Otis,

Update _ After I made this post, I investigated a little further. Since couple of days I made Device hierarchy "abstract" (although the abstract keyword is not used). And there is due to legacy code 1 device in my table that has the Device discriminator. This does not happens for the resource hierarchy and is probably the reason of the "error". When I changed this discriminator to another (existing) discriminator value, the query is fetched just fine.

When a base entity is "abstract" I assume that it's discriminator should not be used. flushed

It seems that a couple of days of holiday were good to me.

Thanks for your help, the "tip/request" for the query dump was the reason to point me to the "Device" discriminator value. But then again as I said before, I would not have expected it in the query... confused _ End Update

Sorry for the delay, but we had "bridge" and national holiday in Belgium. What follows is the full dump from my trace file for the query that is causing the error

I hope that this helps.

I see that all discriminators are passed. Only the "Device" discriminator is strange to me, as this is the base type. But then again, when I check this with the Person query which works just fine, I see that the base type "Resource" is also passed together with the other discriminator values.



Method Exit: CreateSelectDQ
Method Exit: CreatePagingSelectDQ: no paging.
Method Enter: CreatePagingSelectDQ
Method Enter: CreateSelectDQ
Method Enter: CreateSelectDQ
Generated Sql query: 
    Query: SELECT [Galantis].[core].[Devices].[DeviceID] AS [F21_0], [Galantis].[core].[Devices].[DeviceReferenceID] AS [F21_1], [Galantis].[core].[Devices].[DeviceParentID] AS [F21_2], [Galantis].[core].[Devices].[DescriptionID] AS [F21_3], [Galantis].[core].[Devices].[Codex] AS [F21_4], [Galantis].[core].[Devices].[Discriminator] AS [F21_5], [Galantis].[core].[Devices].[Enabled] AS [F21_6], [Galantis].[core].[Devices].[ExternalID] AS [F21_7], [Galantis].[core].[Devices].[CommunicationChannelType] AS [F21_8], [Galantis].[core].[Devices].[IpAddress] AS [F21_9], [Galantis].[core].[Devices].[PortNumber] AS [F21_10], [Galantis].[core].[Devices].[BaudRate] AS [F21_11], [Galantis].[core].[Devices].[StopBits] AS [F21_12], [Galantis].[core].[Devices].[DataBits] AS [F21_13], [Galantis].[core].[Devices].[Parity] AS [F21_14], [Galantis].[core].[Devices].[PortName] AS [F21_15], [Galantis].[core].[Devices].[Handshake] AS [F21_16], [Galantis].[core].[Devices].[Encoding] AS [F21_17], [Galantis].[core].[Devices].[GsmNumber] AS [F21_18], [Galantis].[core].[Devices].[Pincode] AS [F21_19], [Galantis].[core].[Devices].[Timeout] AS [F21_20], [Galantis].[core].[Devices].[RetryCount] AS [F21_21], [Galantis].[core].[Devices].[DnsHostName] AS [F21_22], [Galantis].[core].[Devices].[BufferLevel] AS [F21_23], [Galantis].[core].[Devices].[CreationUser] AS [F21_24], [Galantis].[core].[Devices].[CreationDate] AS [F21_25], [Galantis].[core].[Devices].[LastChangedUser] AS [F21_26], [Galantis].[core].[Devices].[LastChangedDate] AS [F21_27], [Galantis].[core].[Devices].[DeviceVersion] AS [F21_28], [Galantis].[core].[Devices].[SiteID] AS [F13_29], [Galantis].[core].[Devices].[AccessDataProcessedID] AS [F13_30], [Galantis].[core].[Devices].[DefaultDirection] AS [F13_31], [Galantis].[core].[Devices].[LastProcessed] AS [F13_32], [Galantis].[core].[Devices].[LastAccessGranted] AS [F13_33], [Galantis].[core].[Devices].[LanguageID] AS [F30_34], [Galantis].[core].[Devices].[Address] AS [F30_35], [Galantis].[core].[Devices].[LastRead] AS [F30_36], [Galantis].[core].[Devices].[LastReadVersion] AS [F30_37], [Galantis].[core].[Devices].[isTimeout] AS [F30_38], [Galantis].[core].[Devices].[FirmNumber] AS [F30_39], [Galantis].[core].[Devices].[HostBuffer] AS [F30_40], [Galantis].[core].[Devices].[ResponseDelay] AS [F30_41], [Galantis].[core].[Devices].[DirectionOnDisplay] AS [F30_42], [Galantis].[core].[Devices].[BeepAtNoAnswer] AS [F30_43], [Galantis].[core].[Devices].[BeepAtMessage] AS [F30_44], [Galantis].[core].[Devices].[InputRegistration] AS [F30_45], [Galantis].[core].[Devices].[DateRegistration] AS [F30_46], [Galantis].[core].[Devices].[Barcode] AS [F30_47], [Galantis].[core].[Devices].[StartSign1] AS [F30_48], [Galantis].[core].[Devices].[StartSign2] AS [F30_49], [Galantis].[core].[Devices].[StartSign3] AS [F30_50], [Galantis].[core].[Devices].[StopSign1] AS [F30_51], [Galantis].[core].[Devices].[StopSign2] AS [F30_52], [Galantis].[core].[Devices].[StopSign3] AS [F30_53], [Galantis].[core].[Devices].[MessageOnDisplay] AS [F30_54], [Galantis].[core].[Devices].[ActivationPeriod] AS [F30_55], [Galantis].[core].[Devices].[RelaisAtAccessControl] AS [F30_56], [Galantis].[core].[Devices].[AccessControlActive] AS [F30_57], [Galantis].[core].[Devices].[CodeRequest] AS [F30_58], [Galantis].[core].[Devices].[AntiPassBack] AS [F30_59], [Galantis].[core].[Devices].[AntiPassBackAbsolute] AS [F30_60], [Galantis].[core].[Devices].[CodeLockout] AS [F30_61], [Galantis].[core].[Devices].[CodeLockoutAbsolute] AS [F30_62], [Galantis].[core].[Devices].[PoseQuestions] AS [F30_63], [Galantis].[core].[Devices].[QuestionPriority] AS [F30_64], [Galantis].[core].[Devices].[CheckAllowedCellPhoneNumbers] AS [F30_65], [Galantis].[core].[Devices].[AllowedCellPhoneNumber1] AS [F30_66], [Galantis].[core].[Devices].[AllowedCellPhoneNumber2] AS [F30_67], [Galantis].[core].[Devices].[F1] AS [F30_68], [Galantis].[core].[Devices].[F2] AS [F30_69], [Galantis].[core].[Devices].[F3] AS [F30_70], [Galantis].[core].[Devices].[F4] AS [F30_71], [Galantis].[core].[Devices].[NumberOfActivationTimes] AS [F30_72], [Galantis].[core].[Devices].[NumberOfCodeRequests] AS [F30_73], [Galantis].[core].[Devices].[NumberOfTimeSliceGroups] AS [F30_74], [Galantis].[core].[Devices].[StepTimeSliceGroups] AS [F30_75], [Galantis].[core].[Devices].[NumberOfResources] AS [F30_76], [Galantis].[core].[Devices].[StepResourcesEnum] AS [F30_77], [Galantis].[core].[Devices].[NumberOfMessages] AS [F30_78], [Galantis].[core].[Devices].[StepMessages] AS [F30_79], [Galantis].[core].[Devices].[NumberOfCars] AS [F30_80], [Galantis].[core].[Devices].[StepCars] AS [F30_81], [Galantis].[core].[Devices].[NumberOfFingers] AS [F30_82], [Galantis].[core].[Devices].[FingerMode] AS [F30_83], [Galantis].[core].[Devices].[EnrollLocally] AS [F30_84], [Galantis].[core].[Devices].[Address] AS [F65_34], [Galantis].[core].[Devices].[isKeyboardFailure] AS [F65_35], [Galantis].[core].[Devices].[isDisplayFailure] AS [F65_36], [Galantis].[core].[Devices].[isReaderFailure] AS [F65_37], [Galantis].[core].[Devices].[isIOFailure] AS [F65_38], [Galantis].[core].[Devices].[FingerMode] AS [F65_39], [Galantis].[core].[Devices].[cfg0] AS [F65_40], [Galantis].[core].[Devices].[cfg1] AS [F65_41], [Galantis].[core].[Devices].[cfg2] AS [F65_42], [Galantis].[core].[Devices].[cfg3] AS [F65_43], [Galantis].[core].[Devices].[cfg4] AS [F65_44], [Galantis].[core].[Devices].[cfg5] AS [F65_45], [Galantis].[core].[Devices].[cfg6] AS [F65_46], [Galantis].[core].[Devices].[cfg7] AS [F65_47], [Galantis].[core].[Devices].[cfg8] AS [F65_48], [Galantis].[core].[Devices].[cfg9] AS [F65_49], [Galantis].[core].[Devices].[cfg10] AS [F65_50], [Galantis].[core].[Devices].[cfg11] AS [F65_51], [Galantis].[core].[Devices].[cfg12] AS [F65_52], [Galantis].[core].[Devices].[cfg13] AS [F65_53], [Galantis].[core].[Devices].[cfg14] AS [F65_54], [Galantis].[core].[Devices].[cfg15] AS [F65_55], [Galantis].[core].[Devices].[clt] AS [F65_56], [Galantis].[core].[Devices].[apt] AS [F65_57], [Galantis].[core].[Devices].[pos] AS [F65_58], [Galantis].[core].[Devices].[inp] AS [F65_59], [Galantis].[core].[Devices].[snr] AS [F65_60], [Galantis].[core].[Devices].[askDirection] AS [F65_61], [Galantis].[core].[Devices].[swallow] AS [F65_62], [Galantis].[core].[Devices].[saldoOnDisplay] AS [F65_63] FROM [Galantis].[core].[Devices]  WHERE ( ( [Galantis].[core].[Devices].[Discriminator] IN (@Discriminator1, @Discriminator2, @Discriminator3, @Discriminator4)))
    Parameter: @Discriminator1 : String. Length: 25. Precision: 0. Scale: 0. Direction: Input. Value: "Data".
    Parameter: @Discriminator2 : String. Length: 25. Precision: 0. Scale: 0. Direction: Input. Value: "Device".
    Parameter: @Discriminator3 : String. Length: 25. Precision: 0. Scale: 0. Direction: Input. Value: "EM3xx".
    Parameter: @Discriminator4 : String. Length: 25. Precision: 0. Scale: 0. Direction: Input. Value: "RegistrationPoint".

Method Exit: CreateSelectDQ
Method Exit: CreatePagingSelectDQ: no paging.

Kind regards, TomV

Walaa avatar
Walaa
Support Team
Posts: 14946
Joined: 21-Aug-2005
# Posted on: 22-Jul-2009 11:07:42   

Glad you have found the source of the error.

Note: For an abstract entity, you should not be able to instantiate it, but the Framework need to... as it needs to fetch such entities in some ocasions, that's why the discrim. value is used.