bug #7331

Updated by Andreas Kohlbecker about 1 year ago

In the `RegistrationWorkingSetService.loadWorkingSetByReferenceID(Integer referenceID)` a `RegistrationWorkingSet` is lodade with the following coede:


List<String> REGISTRATION_INIT_STRATEGY = Arrays.asList(new String []{
// typeDesignation
"typeDesignations.typifiedNames.typeDesignations", // important !!
// name
"name.typeDesignations", // important !!"
// institution

Reference reference = repo.getReferenceService().find(referenceID);
Pager<Registration> pager = repo.getRegistrationService().page(Optional.of(reference), null, null, null, REGISTRATION_INIT_STRATEGY);
return new RegistrationWorkingSet(makeDTOs(pager.getRecords()));


This usually works, but with a specific data set the `pager` contains `Registrations` where `authorship`
properties of the `nomenclaturalReferences` are not initializes even if the `AdvancedBeanInitializer` apparently is doing the initialization properly (also confirmed by debugging):

[] - processing /name.nomenclaturalReference
[] - invoke initialization on /name.nomenclaturalReference beans of class TaxonName ...
[] - bulk load /name.nomenclaturalReference
[] - bulk load /name.nomenclaturalReference - DONE
[] - processing /name.nomenclaturalReference.authorship
[] - invoke initialization on /name.nomenclaturalReference.authorship beans of class Reference ...
[] - bulk load /name.nomenclaturalReference.authorship
[] - bulk load beans of class TeamOrPersonBase
[] - SELECT c FROM TeamOrPersonBase as c WHERE IN (:idSet)
[] - initialize bulk loaded beans of class TeamOrPersonBase: [1383]
[] - bulk load - DONE

The actual initialization takes place in `AdvancedBeanInitializer.bulkLoadLazyBeans(BeanInitNode node)`. Here a strange behavior can be observed in these special cases:


private void bulkLoadLazyBeans(node node) {
for (Class<?> clazz : node.getLazyBeans().keySet()){
Set<Serializable> idSet = node.getLazyBeans().get(clazz);
String hql = " SELECT c FROM %s as c %s WHERE IN (:idSet) ";
hql = String.format(hql, clazz.getSimpleName(), autoInit.leftJoinFetch); // hql = "SELECT c FROM TeamOrPersonBase as c WHERE IN (:idSet)"
Query query = genericDao.getHqlQuery(hql);
query.setParameterList("idSet", idSet);
List<Object> list = query.list();

Now the TeamOrPersonBase entities are initialized.
**However, checking the `parent` object contained in the `node` object passed as parameer reveals that the 'authorship' proxy in the object graph has not been initialized.**

Preloading the reference in the `RegistrationWorkingSetService.loadWorkingSetByReferenceID(Integer referenceID)` method avoids the problem (in the below code only relevant lines are shown)


Reference reference = repo.getReferenceService().find(referenceID);


Since this behavior is data dependent, I serialized the fully initialized registrations as loaded in the `RegistrationDaoHibernateImpl.list(Optional<Reference> reference, Collection<RegistrationStatus> includedStatus, Integer limit, Integer start, List<String> propertyPaths)`. attachment:registrations-fully-initialized.ser propertyPaths)` method before and after the execution of the `DefaultBeanInitializer`. attachment:registrations-before-initialization.ser can be used to restore the original data by deserializing and persisting the objects to a cdm-database (version 4.15.0-SNAPSHOT) :


try {
FileInputStream fin = new FileInputStream("registrations-fully-initialized.ser");
ObjectInputStream oin = new ObjectInputStream(fin);
List<Registration> registrationsDeserialized = (List<Registration>) oin.readObject();
} catch (ClassNotFoundException | IOException e) {
// TODO Auto-generated catch block


Add picture from clipboard (Maximum size: 40 MB)