Breaking Changes
List of changes in each version that breaks backward compatibility from a previous version.
Version 4.18
If you use undocumented internal classes TInsertCommand or TUpdateCommand, be aware that the type of the insert and update fields have changed. You now have to create a TInsertSQLField and TUpdateSQLField respectively, and you must define a value for the ParamName property.
Old behavior:
Command := TInsertCommand.Create;
Command.InsertFields.Add(TSQLField.Create(SQLTable, 'Name'));
New behavior:
Command := TInsertCommand.Create;
Command.InsertFields.Add(TSQLInsertField.Create(SQLTable, 'Name', 'ParamName'));
The same applies for TUpdateCommand and TSQLUpdateField.
Version 3.11
TCriteria.Open<T> now returns ICriteriaCursor<T>.
This is a change that should not affect any existing code. But in any case you have a type mismatch error when retrieving a cursor with Open and saving the reference to a variable, just change the type of the variable and everything should work as expected.
Version 3.2
Merging transient objects with proxy collections was ignoring the collection content (TObjectManager.MergeListLegacyBehavior).
Updating/Merging objects with proxied associations that were not modified was not clearing the value.
More info here.
Version 2.9
- Object manager now uses transactions by default. More info here.
Version 2.4
The process of merging objects (Merge method) has improved, but this created a breaking change. In previous versions, if you tried to merge an object without id, an exception would be raised. But if you tried to merge an object which had an association that pointed to an object with no id, nothing would happen and that association property would remain unchanged. It was an inconsistent behavior but no exception was raised. Starting from version 2.4, if you try to merge an object with no id, a copy of that instance will be saved. If it's an association, the instance will be replaced. This is a breaking change.
For example, consider the following code:
Customer := TCustomer.Create;
Customer.Id := 1;
Country := TCountry.Create;
Country.Name := 'New Country';
Customer.Country := Country;
MergedCustomer := Manager.Merge<TCustomer>(Customer);
Customer has an id but Country has not. Customer will be merged and a different instance will be returned and put in MergedCustomer variable. Previous to version 2.4, MergedCustomer.Country will point to the same instance pointed by Country variable, and nothing would happen in database. From version 2.4 and on, a copy of Country object will be saved in database, and MergedCustomer.Country will point to that new instance, which is different from the instanced referenced by Country variable. You should destroy the Country instance.
Version 2.2
Packages were restructured to use LIBSUFIX, which means DCP (Delphi
Compiled Package) files won't have the a suffix indicating Delphi
version. For example, in previous versions, the compiled package file
for Delphi XE3 would be aureliusxe3.dcp
. From version 2.2 and on, file
name will be simply aurelius.dcp
. Your application might be affected by
this if you have packages that requires Aurelius packages. You will have
you update your package files to require package "aurelius" instead of
requiring package "aureliusxe3" (or whatever Delphi version you use).
BPL files are unchanged, still keeping delphi version suffix
(aureliusxe3.bpl
).
Version 3.2 - Breaking Changes
Merging transient objects with proxy collections was ignoring the collection content.
This versions fixes a bug that might break existing code that was relying on such bug to work.
Suppose you have a list with a property using lazy-loaded association (using Proxy):
TCustomer = class
{...}
FAddresses: Proxy<List<TAddress>>;
If you initialize such class and Merge it using an existing customer Id:
Customer := TCustomer.Create;
Customer.Id := 5;
Manager.Merge<TCustomer>(Customer);
Manager.Flush;
Expected behavior would be that all the existing Addresses associated with Customer which Id=5 would be disassociated from it (or deleted if the association cascade included RemoveOrphan type.
However, for versions below 3.2, the property was being ignored when merging and the addresses were kept. So you must be sure that your code doesn't rely on such behavior, otherwise you might get some changes in data.
If you want to keep the old behavior, you can set a specific property in the object manager:
Manager.MergeListLegacyBehavior := True;
This will keep the old (and wrong) behavior.
Updating/Merging objects with proxied associations that were not modified was not clearing the value.
On the other hand, suppose you have the same situation but with a single entity association:
TCustomer = class
{...}
FCountry: Proxy<TCountry>;
If you create a new instance and update (or merge) it, leaving Country blank:
Customer := TCustomer.Create;
Customer.Id := 5;
Manager.Update(Customer); // or Manager.Merge<TCustomer>(Customer);
Manager.Flush;
Expected behavior would be that Country of customer with id = 5 in the database would be cleared.
However, for versions below 3.2, the value was being ignored and Country property was left unchanged. So be careful with the update because after updating existing code might behave differently (even though it was relying on a bug).
Version 2.9 - TObjectManager.UseTransactions
As of version 2.9, TObjectManager includes a property UseTransactions. This property is true by default, meaning the behavior is different from previous versions. When true, the manager will create transactions for its internal operations (for example, when you call Save or Remove). This is to make sure that all SQL performed by the internal operations are executed successfully or all is reverted in case of error at any point.
In our (huge) test suite, we didn't detect any problem with backward compatibility, no regressions. But in any case you find an issue with version 2.9, please be aware of this change and consider if that can be the cause of the problem.
You can switch to previous behavior by setting that property to false, or globally using the global configuration.