Любая цель использования LoadableDetachableModel в DataProvider? - PullRequest
0 голосов
/ 09 января 2012

Поскольку до сих пор не совсем ясно, когда следует использовать LDM, я попытался провести простой тест памяти.Я создал DataView с DataProvider, который просто создает список из нескольких сотен объектов с большими данными внутри (длинная строка):

    private class HeavyDataProvider implements IDataProvider<HeavyBean> {

    @Override
    public void detach() {
    }

    @Override
    public Iterator<? extends HeavyBean> iterator(int first, int count) {
        List<HeavyBean> l = newArrayList();
        for (int i = 0; i < this.size(); i++) {
            l.add(new HeavyBean());
        }
        return l.iterator();
    }

    @Override
    public IModel<HeavyBean> model(HeavyBean heavyBean) {
        return new CompoundPropertyModel<HeavyBean>(heavyBean);
    }

    @Override
    public int size() {
        return 500;
    }
}

Использование DebugBar от wicket позволяет увидеть страницу размером 5 МБ.В javadoc DataProvider указано, что возвращаемая модель в приведенном выше методе модели обычно является съемной , поэтому я изменил этот метод на:

        @Override
    public IModel<HeavyBean> model(final HeavyBean heavyBean) {
        return new LoadableDetachableModel<HeavyBean>() {

            @Override
            protected HeavyBean load() {
                return heavyBean;
            }
        };
    }

Наивно я ожидал, что размер страницы будетбыть сокращен в значительной степени сейчас, так как тяжелые бобы больше не будут частью модели.Фактический результат: 5 МБ.Поскольку модель отсоединяет heavyBean, это должно означать, что что-то еще удерживает ее (DataView? Item?).

Я видел другие примеры, когда DataView и DataProvider объединяются аналогичным образом, но для меня этоНепонятно, в чем смысл, поскольку, похоже, это не имеет никакого значения в отношении размера страницы / использования памяти.

Итак, я понимаю / делаю что-то неправильно (вероятно) или LDM бесполезен в DataProviders?Дополнительный вопрос (извините), в каком сценарии вы бы использовали LDM?

Ответы [ 2 ]

2 голосов
/ 09 января 2012

Ваша реализация LDM просто неверна. Он содержит прямую ссылку на сам бин и просто возвращает его. Таким образом, бин будет сериализован вдоль модели, что делает его совершенно бессмысленным.

Вы должны сделать что-то вроде этого:

@Override
public IModel<HeavyBean> model(final HeavyBean heavyBean) {
    final Integer id = heavyBean.getId();
    return new LoadableDetachableModel<HeavyBean>() {
        @Override
        protected HeavyBean load() {
            return ServiceLocator.get(HeavyDao.class).get(id);
        }
    };
}

Если вы используете модуль wicket-ioc, ссылка на HeavyDao может быть вставлена ​​в прилагаемую страницу / компонент.

Я думаю, Wicket действительно прост в использовании, но вы должны понимать основы Java-сериализации, иначе вы можете получить очень раздутый http-сеанс.

0 голосов
/ 09 января 2012

Чтобы LDM работал, вам фактически нужно отсоединить данные в методе detach (). LDM предназначены для использования с базами данных, где вы можете восстановить / загрузить данные по следующему запросу, зная только идентификатор. Таким образом, в detach () вы отбрасываете все данные, кроме идентификатора (или того, что вам нужно для перекодировки данных при необходимости) и в load () (это правильно? Вы не можете заблокировать API прямо сейчас), вы будете восстановить данные.

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

...