Coldfusion, Coldbox, Hibernate: запрос с выделением
У меня проблемы с проектом, и я обращаюсь к сообществу за помощью.
Я предвосхищу это, сказав, что я не очень знаком с ColdFusion (я немного возился с ним 12 лет назад, и я понимаю, что он эволюционировал с тех пор), и я совсем не знаком с Coldbox или Hibernate.
У меня есть обработчик Coldbox (показан ниже), который извлекает список объектов событий из базы данных и возвращает его в формате JSON. В настоящее время это работает нормально (все, что находится за пределами ПРОБЛЕМНОЙ ОБЛАСТИ). Однако теперь у нас есть необходимость отфильтровать список событий по другой таблице, называемой квантификации. По сути, мне нужно сопоставить все события, которые а) имеют квантификации, связанные с ними, и б) имеют хотя бы одну квантификацию со статусом "Активно".
У меня было несколько логических способов справиться с этим. Первым (и не идеальным) было просто захватить все мои результаты, а затем отфильтровать их после этого в виде набора циклов. Тем не менее, это дорого и может привести к путанице, поэтому я бросил эту идею.
Вторым было сделать объединение в таблице "Квантификации", возвращая все активные квантификации и соответствующие им события. Тем не менее, я сталкиваюсь с дубликатами и Coldbox's resultTransformer
на самом деле, кажется, не работает - DISTINCT_ROOT_ENTITY
не возвращает отдельные объекты. (У меня также есть серьезная нехватка ссылок на код, и у меня нет способа легко пройти по коду.)
Моя последняя идея заключается в следующем: для каждого события выполните подзапрос таблицы Quantifications для квантификаций, связанных с событием, а затем получите количество активных. Если счет положительный, верните событие.
Как я могу заставить это работать с Coldbox и Hibernate? Я знаю, что я хочу сделать (и как логически решить проблему), но я очень мало представляю, как сделать это в этой системе, с этими инструментами и этим синтаксисом, и у меня, к сожалению, очень мало времени, чтобы понять это из. Спасибо!
<cfscript>
component extends="handlers._jsonApi" {
property name='statusService' inject='entityService:EventStatus';
property name='departmentService' inject='entityService:Department';
property name='myEventService' inject='id:myEventService';
property name='quantificationService' inject='entityService:Quantification';
///api/v1/events?departmentId=[XXX]&date=[2013-08-02]&showEventsWithoutQuantifications[false|true]
function index(event,rc,prc){
var myEventCriteria = myEventService.newCriteria();
//if a date is passed, display events occuring that date
if (StructKeyExists(rc, "date")){
if (isDate(rc.date)){
var date = createODBCDateTime(rc.date);
} else {
addMessage("The date passed (#rc.date#) is invalid. The date must be in the following format: YYYY-MM-DD.", "error");
return;
}
} else {//else display events occurring today
var date = createODBCDateTime(now());
}
myEventCriteria.le("startDate", date);
myEventCriteria.ge("endDate", date);
//if a department id is passed, restrict events to that department
if (( StructKeyExists(rc, "departmentId")) AND (len(rc.departmentId))){
var departmentId = rc.departmentId;
var department = departmentService.findWhere(entityName="Department", criteria={departmentId=departmentId});
if (isNull(department)){
addMessage("'#rc.departmentId#' is not a valid departmentId.", "error");
return;
}
myEventCriteria.isEq("department", department);
}
var showEventsWithoutQuantifications = false;
if (StructKeyExists(rc, "showEventsWithoutQuantifications")){
if (rc.showEventsWithoutQuantifications) showEventsWithoutQuantifications = true;
}
if (NOT showEventsWithoutQuantifications){
myEventCriteria.isNotEmpty('quantifications');
}
/* PROBLEM AREA */
// Filter events to only include those that have approved quantifications.
var statusId = 150;
var status = statusService.findWhere(entityName="EventStatus", criteria={eventStatusOrder=statusId});
myEventCriteria.createAlias("quantifications", "qt").isEq("qt.status", status);
myEventCriteria.withProjections(countDistinct="eventID");
myEventCriteria.resultTransformer( myEventCriteria.DISTINCT_ROOT_ENTITY );
/* // PROBLEM AREA */
var recordCount = myEventCriteria.count();
//the order needs to be set after the count is retrieved, or it returns an error
//myEventCriteria.order('startDate', 'asc');
myEventCriteria.order('eventID', 'asc');
var pageSize = getSetting("defaultPageSize");
if (StructKeyExists(rc, "pageSize") AND Len(rc.pageSize)) pageSize = rc.pageSize;
myEventCriteria.maxResults(pageSize);
if (recordCount GT pageSize){
var firstResult = 0;
var pageNumber = 1;
var pageCount = Ceiling(recordCount / pageSize);
if (StructKeyExists(rc, "pageNumber") AND Len(rc.pageNumber)){
pageNumber = rc.pageNumber;
if (pageNumber LT 0 OR pageNumber GT pageCount){
addMessage("The pageNumber must be between 1 and #pageCount#", "error");
return;
}
firstResult = (pageNumber - 1) * pageSize;
myEventCriteria.firstResult(firstResult);
}
var paging = StructNew();
paging['pageSize'] = pageSize;
paging['pageNumber'] = pageNumber;
paging['pageCount'] = pageCount;
paging['recordCount'] = recordCount;
prc.response['paging'] = paging;
}
prc.response['events'] = objectsToStructs(myEventCriteria.list(), "eventID,eventName,eventCity,eventState,eventVenue,startDate,endDate,justfication,department.departmentID,department.departmentName,country.countryID,country.countryCode,country.countryName,country.countryRegion,signInSummary.signInSummaryID,signInSummary.signInSummary,serviceType.serviceTypeID,serviceType.serviceTypeName" );
}//end index
}//end component
</cfscript>