2014-12-16 1 views
1

Вот сделка:объекта модификация непоследовательность рамочного Play 2.2.X

public static List<Survey> getFilteredSurveys(Municipality municipality, Company company) { 
    String sql = "SELECT DISTINCT id FROM survey INNER JOIN " + 
        "(SELECT SURVEY_ID FROM publicity INNER JOIN brand "+ 
        "ON publicity.brand_id=brand.id WHERE brand.company_id="+company.getId()+") "+ 
        "ON survey_id=survey.id WHERE survey.municipality_id="+municipality.getId(); 
    RawSql rawSql = RawSqlBuilder.parse(sql).create(); 
    List<Survey> surveys = Ebean.find(Survey.class).setRawSql(rawSql).findList(); 
    for (Survey survey : surveys) { 
     List<Publicity> publicities = new ArrayList<>(); 
     for (Publicity publicity : survey.publicities) { 
      if(publicity.getBrand().getCompany() == company){ 
       publicities.add(publicity); 
      } 
     } 
     survey.setPublicities(publicities); 
    } 
    return surveys; 
} 

Это приложение предназначено для измерения рекламных в данном месте, Таким образом, люди загрузить «Обзор» места, содержащего все " Публичность "это место.

Эта функция должна возвращать список, Каждое обследование имеет список, И каждый Publicity имеет марка, которая связана с Компанией (например, кока-колы. -> Coca-Cola Co.)

Что Я пытаюсь сделать следующее: Учитывая компанию, показать все опросы, содержащие «Coca Cola Co.», гласности, но показывая только рекламу, принадлежащую «Coca Cola Co.»,

У меня есть контроллер «Surveys», который получает форму с муниципалитетом и компанией, называет этот метод, и он отображает представление с его результатом.

Это часть шаблона вида:

@(surveys: java.util.List[Survey]) 

    @for(survey <- surveys){ 
     @for(publicity <- survey.getPublicities){ 
      <tr> 
       <td>@publicity.getBrand.getName</td> 
       <td>@publicity.getType.getName</td> 
       <td>@publicity.getSquareMeters</td> 
      </tr> 
    } 
} 

Проблема: несмотря на то, что я удалил некоторые из рекламных каждого обследования, все рекламных отображаются в представлении. Почему это происходит? Я знаю, что я не настаиваю на изменениях, и я не хочу, я просто хочу временно запутать данные, чтобы пользователь видел только рекламу, принадлежащую данной компании. Почему эта точка зрения не используется с использованием опросов, поскольку они даны ей, изменены?

+0

Я думаю, что сравнение в следующем 'if' неверно' if (publicity.getBrand(). GetCompany() == company) '.Из вашего параметра 'company' это похоже на« Company' Object », но вы сравниваете его с помощью' == ', который должен быть действительным для« Целых чисел »для« Объекта », вы должны использовать' .equals'. Это может помочь вам. – Sivakumar

+0

@ Сивакумар, спасибо, но я уже проверил результат этого метода, и полученные в результате рекламы - это то, что я ожидал, только те, которые принадлежат данной компании. – alejandrociatti

ответ

-1

Итак, я нашел исправить, Моего исправления было:

for (Survey survey : surveys) { 
     survey.getAddress(); //This line fixes the issue 
     List<Publicity> publicities = new ArrayList<>(); 
     for (Publicity publicity : survey.publicities) { 
      if(publicity.getBrand().getCompany() != null){ 
       if(publicity.getBrand().getCompany().getId().equals(company.getId())){ 
        publicities.add(publicity); 
       } 
      } 
     } 
     survey.setPublicities(publicities); 
    } 

Я думаю, что проблема заключается в том, как ebean лениво создает экземпляр объектов, несмотря на установление рекламных до FetchType.EAGER, а также тот факт, что выход от этой функции был ожидаемый, а также проверка surveys в контроллере, казалось, была в порядке, а также @println(surveys) в представлении показывали только рекламу, соответствующую выбранной вами компании.

+0

Похоже, что survey.publicities - это доступ к полю и не вызывает ленивую загрузку (ну, как правило, но не может быть основано на улучшении Play). –

+1

Просто сказать ... вам не нужно «гадать» о ленивой загрузке с Ebean. Включите ведение журнала и в журналах, которые вы увидите в типе записи журнала сводки запросов [+ lazy] ... а также добавьте лишние вещи туда, чтобы указать на «исходный запрос». Так что на самом деле нет необходимости догадываться об этом. –

0

На самом деле я помещу это в ответ ...

Вы должны смотреть на SQL, выполненные в журнале (потому что я подозреваю, что вы получаете N + 1) здесь, и вы могли бы довольно легко избежать.

Возможно, вы захотите изменить свой необработанный sql, чтобы включить столбцы publicities в предложение select (name, type, squareMeters), чтобы избежать дополнительных запросов.

В качестве альтернативы вы можете добавить fetch ("publicities") к запросу (чтобы они были запрограммированы с помощью запроса на соединение 100 за раз).

относятся также к: https://github.com/ebean-orm/avaje-ebeanorm/issues/223 ... RawSql который включает в себя OneToMany не работает

https://github.com/ebean-orm/avaje-ebeanorm/issues/224 ... Улучшение добавления RawSqlBuilder.tableAliasMapping()

В идеале вы бы иметь возможность использовать 4.5 .2 и воспользоваться этим исправлением и этим улучшением.