Problem with latest update 4.12

I released an update to my application last night, with the latest version of Aurelius (4.12). This morning, I received e-mails from many users who were seeing access violations throughout the app. As nothing major had changed in my code, I started looking at the latest update to Aurelius.

The following not in the change logs seemed to point to something. Tracking through my code, I could see entities that maybe should have been nil but seemed to have values, although they were invalid.

As this shut down our whole lab, I needed a fix quickly so rolled back to Aurelius 4.11 and the errors all vanished. But if I'm to be able to upgrade Aurelius and Sparkle etc. in the future, I'm going to need to find the cause of these errors.

The change note isn't very clear on what has actually changed in the code - the past/present tense doesn't make sense, so I can't tell if TCustomer is nil, TInvoice was returned before with a nil for TCustomer, but now TInvoice isn't returned at all (that change would break things - nil is valid, and I check for it), or if TInvoice wasn't returned before but now it is, in which case what would TCustomer be set to. Could you explain the change in a bit more detail so that I can try to find the parts of my code that don't work with the change - although a change that breaks code that has worked for years is a scary change.

"Fixed : When retrieving entities having associations that are restricted by Where attribute, the entity was not being retrieved if the association didn't exist in database. For example, suppose an entity TInvoice with an associated TCustomer entity. Such TCustomer entity has a Where attribute restricting its usage. When retrieving a TInvoice entity, if the associated customer in the database was null, the TInvoice object will not be returned, instead the result will be nil (as if the invoice didn't exist in the database)."

Hello Dave,

I'm sorry for the confusion in the what's new text. I will try to explain it with an example. Suppose you have two entities mapped like this (only the relevant parts):

[Where('Deleted = False')]
TCustomer = class

TInvoice = class
  FCustomer: TCustomer;

In other words: you have customers associated to invoices. And those customers are also filtered by the expression "Deleted = False", i.e., if the database field Deleted = True, the customer will be treated as if it not exist (it will not be retrieved).

Now suppose you have a Customer with Id = 1, and Deleted = True. If you do:

Customer := Manager.Find<TCustomer>(1);
// Customer returns nil

Aurelius will retrieved Customer = nil, even though it does exist in database. That's expected and this behavior did not change.

Now, supposed you have an Invoice in database with ID = 5, and the Customer_ID field is 1 (meaning the invoice is associated with the deleted customer with id = 1.

When you do this:

Invoice := Manager.Find<TInvoice>(5);

// In previous version 4.11: 
// Invoice = nil

// In version 4.12:
// Invoice <> nil
// Invoice.Customer = nil

Version 4.12 will do what is expected: It WILL retrieve an invoice object representing the object in the database, but the FCustomer field will become nil (because the customer is filtered out by the [Where] clause).

In version 4.11, the Invoice was not being retrieved - the result of the Find would be nil.

I hope it's clear now.

Wagner R. Landgraf2020-04-14 21:14:00

Yes, thanks, that's clearer.

Now I know to look for something being retrieved, when before it wasn't. That would make sense for some of the access violations that we are seeing.