What is the correct way to handle collections of model objects in Wicket?

吃可爱长大的小学妹 提交于 2019-12-11 05:05:40

问题


I am looking for some assistance or guidance on the best way to handle collections of objects in Wicket that won't have a devastating impact on session size. Obviously wrapping an object with any of Wicket's IModel classes is ideal, but what is the best way to do that when working with a collection of objects (e.g. a collection of search results).

I have had success using LoadableDetachableModel when working with an individual object, but I appear to be getting a java.io.NotSerializableException intermittently when shutting down Tomcat. Initially, I thought I was safe but the exception being thrown suggests otherwise.

This is the code (edited for brevity):

public class CandidateSearch extends BasicPage {

private static final long serialVersionUID = 1L;
private CandidateService service = new CandidateService();

public CandidateSearch() {
    ListView<Candidate> listView = new ListView<Candidate>("candidates", service.search()){

        private static final long serialVersionUID = 1L;

        @Override
        protected void populateItem(ListItem<Candidate> item) {
            Candidate candidate = (Candidate) item.getModelObject();

            PageParameters pars = new PageParameters();
            pars.add("id", candidate.getId());
            Link<String> candidateLink = new BookmarkablePageLink<String>("candidateLink", CandidateDetails.class, pars);

            candidateLink.add(new Label("candidateId", "ID-" + new Long(candidate.getId()).toString()));

            item.add(candidateLink);
            item.add(new Label("name", candidate.getFirstName() + " " + candidate.getLastName()));
            item.add(new Label("location", candidate.getCity() + ", " + candidate.getState()));
        }

    };

    add(listView);

}

}

NOTE: service.search returns an java.util.List typed as Candidate.


回答1:


When you construct the ListView like that, your Candidate objects will not be detachable...that's why you're getting the java.io.NotSerializableException.

I'm not sure if this is best practices or not, but my strategy is to convert the list of objects into a LoadableDetachableModel of a List. I have a utility method like this:

public static <T> IModel<? extends List<T>> convertToListViewModel(List<T> objects) {

    final Class<? extends List> listClass = objects.getClass();

    // NOTE: you will need to implement the toLoadableDetachableModels method
    List<IModel<T>> asModels = toLoadableDetachableModels(objects);

    return new LoadableDetachableModel<List<T>>() {
        @Override
        protected List<T> load() {
            List<T> results = ClassUtils.newInstance(listClass);
            for(IModel<T> model : asModels) {
                results.add(model.getObject());
            }
            return results;
        }
    };
}

You could use this method to wrap the results of service.search(), and then not only should you should be rid of that error, but your objects will require much less session storage space.




回答2:


The process suggested by stevevis of converting your list to a [LoadableDetachableModel][1] is reasonable if you want to stick with something close to your current basic architecture.

A bigger change that would work as well and for some purposes maybe better would be to switch to using a DataView, so that the data shown comes from an implementation of IDataProvider as needed and is not held as you are doing in a List at all.

Good example code for these and other repeaters can be found at the wicket examples site.



来源:https://stackoverflow.com/questions/14166942/what-is-the-correct-way-to-handle-collections-of-model-objects-in-wicket

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!