PageList<MeasurementDefinition> definitions;
Map<Integer, Long> definitionIntervalMap = new HashMap<Integer, Long>();
Map<Integer, Boolean> definitionEnabledMap = new HashMap<Integer, Boolean>();
if (context.type == EntityContext.Type.ResourceTemplate) {
MeasurementDefinitionCriteria criteria = new MeasurementDefinitionCriteria();
criteria.addFilterResourceTypeId(context.resourceTypeId);
CriteriaQueryGenerator generator = new CriteriaQueryGenerator(subject, criteria);
CriteriaQueryRunner<MeasurementDefinition> queryRunner = new CriteriaQueryRunner(criteria, generator,
entityManager);
definitions = queryRunner.execute();
for (MeasurementDefinition definition : definitions) {
definitionIntervalMap.put(definition.getId(), definition.getDefaultInterval());
definitionEnabledMap.put(definition.getId(), definition.isDefaultOn());
}
} else {
// Do general criteria setup.
MeasurementScheduleCriteria criteria = new MeasurementScheduleCriteria();
switch (context.type) {
case Resource:
criteria.addFilterResourceId(context.resourceId);
break;
case ResourceGroup:
criteria.addFilterResourceGroupId(context.groupId);
break;
case AutoGroup:
criteria.addFilterAutoGroupParentResourceId(context.parentResourceId);
criteria.addFilterAutoGroupResourceTypeId(context.resourceTypeId);
break;
}
criteria.setPageControl(pc); // for primary return list, use passed PageControl
pc.addDefaultOrderingField("definition.displayName");
// Get the core definitions.
CriteriaQueryGenerator generator = new CriteriaQueryGenerator(subject, criteria);
// We previously used the following altered projection for the criteria query:
//
// generator.alterProjection(" distinct measurementschedule.definition");
//
// Hibernate4 no longer allowed for the generated criteria JPQL for this projection:
//
// SELECT distinct measurementschedule.definition
// FROM MeasurementSchedule measurementschedule
// LEFT JOIN measurementschedule.definition orderingField0
// WHERE ( measurementschedule.resource.id IN ( :resourceId ) )
// ORDER BY orderingField0.displayName ASC
//
// It causes:
// SQLGrammarException: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list
//
// In essence, using DISTINCT now requires that we use the LEFT JOIN alias in the select
// list. To support this we could probably have made some tricky coding changes to the
// generator. But seeing that this would be to support non-default criteria queries (i.e
// the altered projection using DISTINCT), of which this is the only one in the code base,
// and we are in control of the order by clause, and therefore are predictably working with
// the JPQL above, I've chosen to just make a change to the custom altered projection, using
// the JPQL to guide me.
generator.alterProjection(" distinct orderingField0");
generator.alterCountProjection(" count(distinct orderingField0)");
CriteriaQueryRunner<MeasurementDefinition> queryRunner = new CriteriaQueryRunner(criteria, generator,
entityManager);
definitions = queryRunner.execute();
// Reset paging -- remove ordering, add group by.
criteria.setPageControl(PageControl.getUnlimitedInstance());
generator.setGroupByClause(" measurementschedule.definition.id ");
// Get the interval results.
generator.alterProjection("" //
+ " measurementschedule.definition.id, " //
+ " min(measurementschedule.interval), " //
+ " max(measurementschedule.interval) ");
Query query = generator.getQuery(entityManager);
List<Object[]> definitionIntervalResults = query.getResultList();
// Get the enabled results.
criteria.addFilterEnabled(true);
generator.alterProjection(" measurementschedule.definition.id, count(measurementschedule.id) ");
query = generator.getQuery(entityManager);
List<Object[]> definitionEnabledResults = query.getResultList();
// Generate intermediate maps for intervals and enabled values.