ActiveWeb: установка / получение модели не работает при вызове в шаблоне

При работе с устаревшей базой данных бывают случаи, когда я не могу правильно настроить отношения, используя belongs_to аннотаций. В этом случае я попытался определить атрибут, указывающий на другой Model Класс с его методами доступа следующим образом:

@Table("INTERVENTION")
@IdName("ITV_ID")
public class Intervention extends Model {
  private InterventionModel interventionModel;

    public InterventionModel getInterventionModel() {
        return interventionModel;
    }

    public void setInterventionModel(InterventionModel interventionModel) {
        this.interventionModel = interventionModel;
    }
}

Я загружаю и настраиваю InterventionModelв классе обслуживания без проблем следующим образом (intervention экземпляр существует):

private void loadInterventionModel(final Intervention intervention) {
        final InterventionModel model = InterventionModel.findById(intervention.getLongId());
        intervention.setInterventionModel(model);
    }

Проблема в том, что это не работает, когда я пытаюсь оценить InterventionModel атрибуты в шаблоне FreeMarker:

"item_code:": ${intervention.intervention_model.imo_internal_code}

Вот сброшенная ошибка:

FreeMarker template error:
An error has occurred when reading existing sub-variable "intervention_model"; see cause exception! The type of the containing value was: extended_hash+string (app.models.Intervention wrapped into f.e.b.StringModel)

Caused by: java.lang.IllegalArgumentException: Attribute: 'intervention_model' is not defined in model: 'class app.models.Intervention.

Что мне здесь не хватает и почему это не работает так, как ожидалось? Как правило, если я объявлю атрибут в модели с его аксессорами (getter и setter), он будет доступен в шаблоне с помощью:

mymodel.my_attribute

2 ответа

Я думаю, я нашел причину. Кажется, что когда вы объявляете переменную экземпляра в модели класса, и эта переменная не относится к доступным атрибутам модели (столбцы таблицы), вы должны использовать snake_case вместо camelCase написание, т.е. вместо объявления:

public class Intervention extends Model {
...
  private InterventionModel interventionModel;

  public InterventionModel getInterventionModel() {
        return interventionModel;
    }

    public void setInterventionModel(InterventionModel interventionModel) {
        this.interventionModel = interventionModel;
    }

}

используйте версию snake_case:

private InterventionModel intervention_model;

public InterventionModel getIntervention_model() {
    return intervention_model;
}

public void setIntervention_model(InterventionModel intervention_model) {
    this.intervention_model = intervention_model;
}

Таким образом, вы сможете получить к нему доступ в шаблоне, как и другие переменные, доступные в модели:

"label": "${intervention.intervention_model.imo_product_label}"

Вначале я считал, что преобразование было сделано автоматически. Вы можете сохранить camlCase verion, - в этом случае вы должны использовать его и в своем шаблоне:

"label": "${intervention.interventionModel.imo_product_label}"

Надеюсь это поможет.

Если ваш класс InterventionModel указывает на устаревшую таблицу, вы можете сделать это:

@Table("INTERVENTION")
@IdName("ITV_ID")
public class Intervention extends Model {
  private InterventionModel interventionModel;

    public InterventionModel getInterventionModel() {
        return interventionModel;
    }

    public void setInterventionModel(InterventionModel interventionModel) {
        this.interventionModel = interventionModel;
    }

    Object getImoProductLabel(){
        return interventionModel.imo_product_label();
    }
}

затем в шаблоне:

"label": "${intervention.imoProductLabel}"

таким образом, вы создадите метод не только для шаблона, но и в других местах кода и абстрагируете свой унаследованный код.

Другие вопросы по тегам