Contactentity class have been renamed, reordered, one was removed, one is new.
String firstnameis equal in both classes, so it has to be the same, pretty much as
lastnameis pretty similar, type is the same too. If there is nothing better for the two, they probably belong together. Same with the other two fields. In the end, the ominous
postalAddressremain. The heuristic can not make sense of that, so it assumes that one thing falls away and the other one is added. In this particular example, that worked perfectly. Well done, heuristic.
PostalAddressinstances were referenced in the application under
linkand the two fields would actually be the same, only now properly typed and named. How should heuristics know that? Nobody could know that either, if he is not privy to the details of the concrete application.
InquiringLegacyTypeMappingResultor. Maybe even one, where the user can "rewire" the mapping itself, write out the mapping, and then return an appropriate result.
count; articleCountmeans: the field named earlier
articleCountin the current version of the class.
count;means: the early field
countshould be ignored during the mapping. More specifically, the values of this field per record.
;articleCountmeans, this is a newly added field, DO NOT try to match it with anything else heuristically.
#is based on official Java syntax, like e.g. in JavaDoc.
com.my.app.entities.Order#com.my.app.entities.ArticleHolder#count; ⤦ com.my.App.entities.Order#com.my.app.entities.ArticleHolder#articleCount
float. Just to copy the four bytes would yield wrong results. It has to be converted, like
float floatValue = (float)intValue;Can it be done? Yes, fully automatic. The class
BinaryValueTranslatorsdoes the job for you, it has a converter function from each primitive to another.
nullis converted to
PersistenceMemberSimilator) and the default implementation thereof calls e.g. just a Levenshtein algorithm for names. You can certainly do that 10 times more clever. Or "more appropriate" for a particular application or programming style. E.g. utilize annotations.
TypeHandlerfor it. If necessary, a
LegacyTypeHandlerwith mapping, but still: there must be a
TypeHandlerfor each TypeId. And a
TypeHandlerneeds a runtime type. That is, ass-backwards, over records that are logically already deleted, but only physically still lying around, now it is again enforced that the erasable entity class must be present. Bummer. One can prevent this: there is a "cleanup" function in the database management logic, which cleans up all logical gaps in the database files (actually copies all non-gaps into a new file and thus deletes the old file altogether). You would have to call it, then all physical occurrences of the unreachable records disappear and you could easily delete the associated class. But that is annoying.
TypeHandlerthat does not need a runtime class. See
PersistenceUnreachableTypeHandler. But be careful: if you are mistaken and an instance of such a type is still referenced somewhere and eventually loaded later at runtime, then the Unreachable handler will throw an exception. At some point during the runtime of the application, not even during initialization. The cleanup provides real security: remove all logical gaps and if then with a deleted class no more error in the initialization occurs, it is really superfluous.
nullin the dummy type handler instead of an instance, are a fire hazard: it may dissolve some annoying situations pleasantly, but it would also mean that existing datasets, potentially entire subgraphs, become hidden from the application. Nevertheless, the database would continue to drag them along, perhaps becoming inexplicably large, and any search for the reason would yield nothing, because the dummy type handler keeps the data records secret. Shortsighted great, but catastrophic in the long run. That's not good. The only clean solution is: you have to know what to do with your data model. As long as there are still available instances, they must also be loadable. The annoying special case above can be defused without side effects. But it can not be more than that, otherwise it will get rid of the chaos, problems and lost confidence in the correctness of the database solution.