ManyValuedAssociation, Proxy, OnValueNotify

Becaue of the lack of support for transactions, removing objects, or refreshing single objects, I've had to turn off OwnsObjects and manage object lifetime myself. I've run into a problem with ManyValuedAssociation proxies. If I attach a hander to TList.OnValueNotify or use TObjectList and set OwnsObjects to true, it seems that the proxy Loaded property is aways true and the association is never loaded. Is that correct?  Is there any workaround?

I found the problem myself. I was doing this in the constructor

 
FApps.SetInitialValue(TList<TApp>.Create);
FApps.Value.OnNotify := OnNotify;
 
Instead it is necessary to do the following:
 
LApps := TList<TApp>.Create;
LApps.OnNotify := OnNotify;
FApps.SetInitialValue(LApps);
 
Accessing the proxy to attach the event handler was causing the problem.
 
 
 
 

Actually, it is not so simple. If the OnNotify handler is attached to the proxy as I did at first,

 
FApps.SetInitialValue(TList<TApp>.Create);
FApps.Value.OnNotify := OnNotify;
 
the proxy is set to loaded and never attempts to load. If I add a TApp object to the FApps list, the OnNotify will fire and free the object. If I set the OnNotify to the list before SetInitialValue like this
 
LApps := TList<TApp>.Create;
LApps.OnNotify := OnNotify;
FApps.SetInitialValue(LApps);
 
the proxy will load, but the event does not fire. In tracing the code, it looks like loading through the proxy creates a new list, but does not attach the event handler to the new list.

Hello, why you had to disable OwnsObjects? It makes it much harder for sure. Aurelius does support transactions, actually.

And yes, when loading the proxies, sometimes the instance of the list object is replaced. You can alternatively just use a TObjectList<TApp> as the base class, since it by default manages the objects.

How does Aurelius support transactions? There is no way I could just clear or recreate the object manager in the case of a rollback. That only works in very simple situations. I would need to tell the user to close the form and start over. I have some very complicated forms with several grids. What approach do you suggest for handling a rollback that doens't require starting over. I really liked using Aurelius until I hit that problem. You have a really nice start on an ORM, but without better support for transactions, it is not very usable except for simple demo type projects. I could probably get around the transaction rollback if it was possible to refresh a single object in the ObjectManager or remove a single object (without removing it from the database). But that is not possible either. I would be very interested to hear what others are doing in this with transactions.

I tried using a TObjectList<TApp> and the result was the same as using a TList. The proxy didn't load. But that may be because I explicitly set the OwnsObjects to false instead of just relying on the default. I'll give it a try again.

What I mean is that Aurelius supports transactions in the sense you can start, commit and rollback transactions. The manager enters into a invalid state indeed. Other ORM frameworks like Hibernate - which is widely used - does that as well. What is missing, indeed, is a way to remove a specific object from the manager, and also refresh a specific object. Such features will be included in TMS Aurelius. 

I must add that you can create a descendant of TList (or TObjectList) and use that class as your container. So you can add your logic to such list (TYourList) and then use it in the manyvaluedassociation properties.

That is what I ended up doing, but it was necessary to make a list that always owns objects and does not rely on events. I first tried a list with an OwnsObjects property, but when the list was recreated, the property was always false, even if it was set to true in the constructor.

It's good to hear that the ability to remove and/or refresh a single object will be included. Is this coming in the next release?

Umanage an object might come in next release, refresh will take a little longer.

Thanks. That may help. I've used both NHibernate and EF4 and they both have good support for transactions. I believe Hibernate does as well. Dephi presents a more difficult problem because it is necessary to consider object lifetime. It wouldn't be such a problem having to destroyy and recreate the ObjectManager that didn't require actually freeing all of the objects.  

For the record, using TObjectList doesn't work. TheTObjectList returned after the load through proxy has OwnsObjects set to false. I had the same problem when I created my own list. Even though I set OwnsObjects to true in the constructor, the list that was created by Aurelius had OwnsObjects set to false.