Project

General

Profile

bug #7331

Updated by Andreas Kohlbecker about 1 year ago


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

~~~java

List<String> REGISTRATION_INIT_STRATEGY = Arrays.asList(new String []{
"blockedBy",
// typeDesignation
"typeDesignations.typeStatus",
"typeDesignations.typifiedNames.typeDesignations", // important !!
"typeDesignations.typeSpecimen",
"typeDesignations.typeName.$",
"typeDesignations.citation",
"typeDesignations.citation.authorship.$",
// name
"name.$",
"name.nomenclaturalReference.authorship.$",
"name.nomenclaturalReference.inReference",
"name.rank",
"name.homotypicalGroup.typifiedNames",
"name.status.type",
"name.typeDesignations", // important !!"
// institution
"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):

~~~
[eu.et.cd.pe.da.in.AdvancedBeanInitializer] - processing /name.nomenclaturalReference
[eu.et.cd.pe.da.in.AdvancedBeanInitializer] - invoke initialization on /name.nomenclaturalReference beans of class TaxonName ...
[eu.et.cd.pe.da.in.AdvancedBeanInitializer] - bulk load /name.nomenclaturalReference
[eu.et.cd.pe.da.in.AdvancedBeanInitializer] - bulk load /name.nomenclaturalReference - DONE
[eu.et.cd.pe.da.in.AdvancedBeanInitializer] - processing /name.nomenclaturalReference.authorship
[eu.et.cd.pe.da.in.AdvancedBeanInitializer] - invoke initialization on /name.nomenclaturalReference.authorship beans of class Reference ...
[eu.et.cd.pe.da.in.AdvancedBeanInitializer] - bulk load /name.nomenclaturalReference.authorship
[eu.et.cd.pe.da.in.AdvancedBeanInitializer] - bulk load beans of class TeamOrPersonBase
[eu.et.cd.pe.da.in.AdvancedBeanInitializer] - SELECT c FROM TeamOrPersonBase as c WHERE c.id IN (:idSet)
[eu.et.cd.pe.da.in.AdvancedBeanInitializer] - initialize bulk loaded beans of class TeamOrPersonBase: [1383]
[eu.et.cd.pe.da.in.AdvancedBeanInitializer] - bulk load - DONE
~~~

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

~~~java

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 c.id IN (:idSet) ";
hql = String.format(hql, clazz.getSimpleName(), autoInit.leftJoinFetch); // hql = "SELECT c FROM TeamOrPersonBase as c WHERE c.id 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)

~~~java

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

~~~

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 can be used to restore the original data by de-serializing deserializing and persisting the objects to a cdm-database (version 4.15.0-SNAPSHOT) :

~~~java

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
e.printStackTrace();
}
~~~

**NOTE: Doing the serializaton in `RegistrationDaoHibernateImpl.list()` also removed the problem described in here!**

Back

Add picture from clipboard (Maximum size: 40 MB)