<h: selectOneMenu> и отложенная загрузка из спящего режима - PullRequest
3 голосов
/ 31 мая 2011

В моем приложении JSF у меня довольно простой фрагмент кода.Я хочу, чтобы пользователь выбрал одно значение из коллекции в <h:selectOneMenu>:

<h:selectOneMenu value="#{bean.value}">
  <f:selectItems value="#{dao.valuesFromDb}" />
</h:selectOneMenu>

#{bean.value} имеет тип Region, а #{dao.valuesFromDb} возвращает список Regions.Проблема в том, что Region в бине лениво загружается из hibernate, который оборачивает его в какую-то оболочку, класс выглядит как my.package.Region_$$_javassist_15@25183.

Если #{bean.value} имеет какое-то установленное значение, его следует предварительно выбрать встраница, если она находится в списке значений (#{dao.valuesFromDb}).Проблема в том, что проверяется методом equals, который возвращает false, потому что типы разные.

Как решить эту проблему?Можно ли заставить JSF не использовать equals, а как-нибудь обработать это сравнение самостоятельно?Переопределение equals, игнорирующее тип, ИМХО действительно плохая идея, поскольку может нарушить equals симметрию.

Ответы [ 3 ]

0 голосов
/ 15 октября 2013

Мы решили решить эту проблему с помощью наших методов Override "equals". Важный трюк - никогда не ссылаться на атрибуты стороннего объекта непосредственно в методе equals, а всегда использовать геттеры. Затем, похоже, Hibernate выявляет правильные значения из объекта javassist.

В вашем случае метод Region equals должен выглядеть примерно так:

@Override
public boolean equals(Object obj) {
    if (this == obj) {return true;}
    if (obj == null) {return false;}
    if (!(obj instanceof Region)) {return false;}

    Region region = (Region) obj;

    if ((name == null) && (region.getName() != null)) {return false;}  // Do NOT use 'region.name' here
    else if (!name.equals(region.getName())) {return false;}           // Do NOT use 'region.name' here
    return true;
}
0 голосов
/ 15 октября 2013

Вместо изменения типа выборки на EAGER, вы можете предварительно загрузить bean-компонент, вызвав геттер Region в действии (контроллера), которое переходит к вашему виду.То есть: просто вызовите метод bean.getRegion().

Таким образом, вы не получите LazyInitializationException (если это то, что вы получаете).

0 голосов
/ 31 мая 2011

В этом случае я бы полностью избежал этой проблемы, охотно выбирая Region в bean.

Манипулирование с помощью equals () приведет к гораздо менее понятному коду, чем простое извлечение информации, которую JSF хочет сравнить.И, как вы указываете, это может иметь непредвиденные последствия.

...