You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@wicket.apache.org by Mostafa Mohamed <es...@gmail.com> on 2009/08/07 19:03:03 UTC

LoadableDetachableModel/Serialization Problem

we're working on wicket/spring/hibernate application (a research
repository).

my SortableDataProvider looks like this.

public class PublicationDataProvider extends SortableDataProvider {
    private IBrowseService browseService;
    private Class<?> type;

    public PublicationDataProvider() {};

    public PublicationDataProvider(IBrowseService browseService, Class<?>
type) {
        this.browseService = browseService;
        this.type = type;
        setSort("title", true);
    }

     public Iterator<IPublication> iterator(int first, int count)
     {
         SortParam sp = getSort();
         return browseService.find(first, count, sp.getProperty(),
sp.isAscending(), type).iterator();
     }

     public int size()
     {
         return browseService.countAll();
     }

     public IModel model(Object object)
     {
         return new DomainObjectModel<IPublication>((IPublication)object);
     }

     public void detach() {}
}

I use it with a dataview on the following panel

package main.java.web.components.browser;

import main.java.domain.publication.IPublication;
import main.java.domain.user.IUser;
import main.java.services.publication.IBrowseService;
import main.java.web.components.content.BasicPanel;

import org.apache.wicket.ajax.AjaxRequestTarget;
import
org.apache.wicket.ajax.markup.html.navigation.paging.AjaxPagingNavigator;
import
org.apache.wicket.extensions.ajax.markup.html.repeater.data.sort.AjaxFallbackOrderByLink;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.spring.injection.annot.SpringBean;

public class BrowsePanel extends BasicPanel {
    @SpringBean
    IBrowseService browseService;

    transient IPublication publication;

    public BrowsePanel(Class<?> type) {
        super("block", "Browse Publications");
        setOutputMarkupId(true);

        final WebMarkupContainer dataContainer = new
WebMarkupContainer("dataContainer");
        dataContainer.setOutputMarkupId(true);
        add(dataContainer);

        PublicationDataProvider pdp = new
PublicationDataProvider(browseService, type);
        final DataView dataView = new DataView("publication", pdp, 10) {
            @Override
            protected void populateItem(Item item) {
                publication = (IPublication) item.getModelObject();
                item.add(new Label("number", "" + (getCurrentPage() * 10 +
item.getIndex() + 1)));
                item.add(new Label("title", publication.getTitle()));

                IModel authorsModel = new LoadableDetachableModel() {
                    @Override
                    protected Object load() {
                        return publication.getAuthorsInOrder();
                    }
                };

                ListView authorsListView = new ListView("author",
authorsModel) {
                    @Override
                    protected void populateItem(ListItem item) {
                        Object author = item.getModelObject();
                        Link authorLink = new Link("authorLink") {
                            @Override
                            public void onClick() {

                            }
                        };
                        if (author instanceof IUser) {
                            authorLink.add(new Label("authorName", ((IUser)
author).getFullName()));
                        }
                        else {
                            authorLink.add(new Label("authorName",
author.toString()));
                            authorLink.setEnabled(false);
                        }
                        item.add(authorLink);
                    }
                };
                item.add(authorsListView);
                item.add(new Label("abstract",
publication.getAbstractText()));
            }
        };

        dataContainer.add(new AjaxFallbackOrderByLink("orderByTitle",
"title", pdp) {
            @Override
            protected void onSortChanged() {
                dataView.setCurrentPage(0);
            }

            @Override
            protected void onAjaxClick(AjaxRequestTarget target) {
                target.addComponent(dataContainer);
            }
        });

        dataContainer.add(dataView);

        AjaxPagingNavigator pager = new AjaxPagingNavigator("pager",
dataView) {
            @Override
            protected void onAjaxEvent(AjaxRequestTarget target) {
                target.addComponent(dataContainer);
            }
        };

        dataContainer.add(pager);
    }
}

when the publication instance variable wasn't transient i would get a wicket
not serializable exception on this field. I've been reading in the forum and
i now know that this is because the loadable detachable model that gets the
list of user objects holds a reference to the publication, (return
publication.getAuthorsInOrder()). transient does solve my problem, however i
have a feeling that something is not right. Is there any elegant way to do
this? Also i'd like to point out that all my domain objects don't implement
the serializable interface and that they implement the IDomainObject
interface that has only a getId() method. I've seen the IDomainObject
interface in WIA and it implements the serializable interface. but isn't
that against the idea of the loadable detachable model?

Re: LoadableDetachableModel/Serialization Problem

Posted by "sky.walker" <es...@gmail.com>.
Thanks igor. i just tried it and it worked. It's so cool property models work
like that.


igor.vaynberg wrote:
> 
> the propertymodel will call the getter function.
> 
> -igor
> 
> On Fri, Aug 7, 2009 at 10:44 AM, sky.walker<es...@gmail.com> wrote:
>>
>> I actually tried that, however my publication object looks like this. (I
>> trimmed it to the relevant parts). as you can see there's no
>> authorsInOrder
>> Property only the authors property which can't be displayed to the user.
>> I
>> have to call getAuthorsInOrder() to retrieve the the list of author
>> objects.
>> Right now i can't change this pojo implementation but i can try to
>> convince
>> the domain model guy. What are my options if it can be changed and if it
>> can't?
>>
>> package main.java.domain.publication;
>>
>> import java.util.*;
>>
>> import main.java.domain.user.IUser;
>>
>> /**
>>  * An abstract publication POJO implementation for the IPublication
>> interface.
>>  *
>>  * @see main.java.domain.publication.IPublication
>>  * @author Karim El-Sayed
>>  */
>> public abstract class Publication implements IPublication {
>>        /**
>>         * The unique id of this publication.
>>         */
>>        private Long id;
>>
>>        /**
>>         * The names of the authors of this publication in the same
>> ordered that
>>         * have been entered by the user as a <code>String</code>
>> separated by
>>         * commas. The authors within the organization has their id
>> entered while
>>         * external authors directly have their name.
>>         */
>>        private String authors;
>>
>>        private Set<IUser> internalAuthors = new HashSet<IUser>();
>>
>>        /**
>>         * Default constructor.
>>         */
>>        public Publication() {
>>        }
>>
>>        @Override
>>        public Long getId() {
>>                return id;
>>        }
>>
>>        @Override
>>        public void setId(Long id) {
>>                this.id = id;
>>        }
>>
>>        @Override
>>        public String getAuthors() {
>>                return authors;
>>        }
>>
>>        @Override
>>        public void setAuthors(String authors) {
>>                this.authors = authors;
>>        }
>>
>>        @Override
>>        public List getAuthorsInOrder() {
>>                List authorsInOrder = new ArrayList();
>>                String[] order = authors.split("#");
>>                for (String author : order) {
>>                        long authorId = isNumber(author);
>>                        if (authorId == -1) {
>>                                authorsInOrder.add(author);
>>                        } else {
>>                                Iterator<IUser> iterator =
>> internalAuthors.iterator();
>>                                while (iterator.hasNext()) {
>>                                        IUser user = iterator.next();
>>                                        if (user.getId() == authorId) {
>>                                                authorsInOrder.add(user);
>>                                                break;
>>                                        }
>>                                }
>>                        }
>>                }
>>                return authorsInOrder;
>>        }
>> }
>>
>>
>> igor.vaynberg wrote:
>>>
>>> instead of
>>>
>>>  IModel authorsModel = new LoadableDetachableModel() {
>>>                    @Override
>>>                    protected Object load() {
>>>                        return publication.getAuthorsInOrder();
>>>                    }
>>>                };
>>>
>>> do
>>>
>>> authorsModel=new PropertyModel(item.getModel(), "authorsInOrder");
>>>
>>
>> --
>> View this message in context:
>> http://www.nabble.com/LoadableDetachableModel-Serialization-Problem-tp24868498p24869176.html
>> Sent from the Wicket - User mailing list archive at Nabble.com.
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
>> For additional commands, e-mail: users-help@wicket.apache.org
>>
>>
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
> 
> 
> 

-- 
View this message in context: http://www.nabble.com/LoadableDetachableModel-Serialization-Problem-tp24868498p24869434.html
Sent from the Wicket - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: LoadableDetachableModel/Serialization Problem

Posted by Igor Vaynberg <ig...@gmail.com>.
the propertymodel will call the getter function.

-igor

On Fri, Aug 7, 2009 at 10:44 AM, sky.walker<es...@gmail.com> wrote:
>
> I actually tried that, however my publication object looks like this. (I
> trimmed it to the relevant parts). as you can see there's no authorsInOrder
> Property only the authors property which can't be displayed to the user. I
> have to call getAuthorsInOrder() to retrieve the the list of author objects.
> Right now i can't change this pojo implementation but i can try to convince
> the domain model guy. What are my options if it can be changed and if it
> can't?
>
> package main.java.domain.publication;
>
> import java.util.*;
>
> import main.java.domain.user.IUser;
>
> /**
>  * An abstract publication POJO implementation for the IPublication
> interface.
>  *
>  * @see main.java.domain.publication.IPublication
>  * @author Karim El-Sayed
>  */
> public abstract class Publication implements IPublication {
>        /**
>         * The unique id of this publication.
>         */
>        private Long id;
>
>        /**
>         * The names of the authors of this publication in the same ordered that
>         * have been entered by the user as a <code>String</code> separated by
>         * commas. The authors within the organization has their id entered while
>         * external authors directly have their name.
>         */
>        private String authors;
>
>        private Set<IUser> internalAuthors = new HashSet<IUser>();
>
>        /**
>         * Default constructor.
>         */
>        public Publication() {
>        }
>
>        @Override
>        public Long getId() {
>                return id;
>        }
>
>        @Override
>        public void setId(Long id) {
>                this.id = id;
>        }
>
>        @Override
>        public String getAuthors() {
>                return authors;
>        }
>
>        @Override
>        public void setAuthors(String authors) {
>                this.authors = authors;
>        }
>
>        @Override
>        public List getAuthorsInOrder() {
>                List authorsInOrder = new ArrayList();
>                String[] order = authors.split("#");
>                for (String author : order) {
>                        long authorId = isNumber(author);
>                        if (authorId == -1) {
>                                authorsInOrder.add(author);
>                        } else {
>                                Iterator<IUser> iterator = internalAuthors.iterator();
>                                while (iterator.hasNext()) {
>                                        IUser user = iterator.next();
>                                        if (user.getId() == authorId) {
>                                                authorsInOrder.add(user);
>                                                break;
>                                        }
>                                }
>                        }
>                }
>                return authorsInOrder;
>        }
> }
>
>
> igor.vaynberg wrote:
>>
>> instead of
>>
>>  IModel authorsModel = new LoadableDetachableModel() {
>>                    @Override
>>                    protected Object load() {
>>                        return publication.getAuthorsInOrder();
>>                    }
>>                };
>>
>> do
>>
>> authorsModel=new PropertyModel(item.getModel(), "authorsInOrder");
>>
>
> --
> View this message in context: http://www.nabble.com/LoadableDetachableModel-Serialization-Problem-tp24868498p24869176.html
> Sent from the Wicket - User mailing list archive at Nabble.com.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: LoadableDetachableModel/Serialization Problem

Posted by "sky.walker" <es...@gmail.com>.
I actually tried that, however my publication object looks like this. (I
trimmed it to the relevant parts). as you can see there's no authorsInOrder
Property only the authors property which can't be displayed to the user. I
have to call getAuthorsInOrder() to retrieve the the list of author objects.
Right now i can't change this pojo implementation but i can try to convince
the domain model guy. What are my options if it can be changed and if it
can't? 

package main.java.domain.publication;

import java.util.*;

import main.java.domain.user.IUser;

/**
 * An abstract publication POJO implementation for the IPublication
interface.
 * 
 * @see main.java.domain.publication.IPublication
 * @author Karim El-Sayed
 */
public abstract class Publication implements IPublication {
	/**
	 * The unique id of this publication.
	 */
	private Long id;
	
	/**
	 * The names of the authors of this publication in the same ordered that
	 * have been entered by the user as a <code>String</code> separated by
	 * commas. The authors within the organization has their id entered while
	 * external authors directly have their name.
	 */
	private String authors;
	
	private Set<IUser> internalAuthors = new HashSet<IUser>();
	
	/**
	 * Default constructor.
	 */
	public Publication() {
	}

	@Override
	public Long getId() {
		return id;
	}

	@Override
	public void setId(Long id) {
		this.id = id;
	}

	@Override
	public String getAuthors() {
		return authors;
	}

	@Override
	public void setAuthors(String authors) {
		this.authors = authors;
	}

	@Override
	public List getAuthorsInOrder() {
		List authorsInOrder = new ArrayList();
		String[] order = authors.split("#");
		for (String author : order) {
			long authorId = isNumber(author);
			if (authorId == -1) {
				authorsInOrder.add(author);
			} else {
				Iterator<IUser> iterator = internalAuthors.iterator();
				while (iterator.hasNext()) {
					IUser user = iterator.next();
					if (user.getId() == authorId) {
						authorsInOrder.add(user);
						break;
					}
				}
			}
		}
		return authorsInOrder;
	}
}


igor.vaynberg wrote:
> 
> instead of
> 
>  IModel authorsModel = new LoadableDetachableModel() {
>                    @Override
>                    protected Object load() {
>                        return publication.getAuthorsInOrder();
>                    }
>                };
> 
> do
> 
> authorsModel=new PropertyModel(item.getModel(), "authorsInOrder");
> 

-- 
View this message in context: http://www.nabble.com/LoadableDetachableModel-Serialization-Problem-tp24868498p24869176.html
Sent from the Wicket - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: LoadableDetachableModel/Serialization Problem

Posted by Igor Vaynberg <ig...@gmail.com>.
you have to chain your models, so instead of

 item.add(new Label("title", publication.getTitle()));

do

item.add(new Label("title", new PropertyModel(item.getModel(), "title"));

instead of

 IModel authorsModel = new LoadableDetachableModel() {
                   @Override
                   protected Object load() {
                       return publication.getAuthorsInOrder();
                   }
               };

do

authorsModel=new PropertyModel(item.getModel(), "authorsInOrder");

that way you never have to hold a reference to the domain object
itself, only a model to it.

-igor


On Fri, Aug 7, 2009 at 10:03 AM, Mostafa Mohamed<es...@gmail.com> wrote:
> we're working on wicket/spring/hibernate application (a research
> repository).
>
> my SortableDataProvider looks like this.
>
> public class PublicationDataProvider extends SortableDataProvider {
>    private IBrowseService browseService;
>    private Class<?> type;
>
>    public PublicationDataProvider() {};
>
>    public PublicationDataProvider(IBrowseService browseService, Class<?>
> type) {
>        this.browseService = browseService;
>        this.type = type;
>        setSort("title", true);
>    }
>
>     public Iterator<IPublication> iterator(int first, int count)
>     {
>         SortParam sp = getSort();
>         return browseService.find(first, count, sp.getProperty(),
> sp.isAscending(), type).iterator();
>     }
>
>     public int size()
>     {
>         return browseService.countAll();
>     }
>
>     public IModel model(Object object)
>     {
>         return new DomainObjectModel<IPublication>((IPublication)object);
>     }
>
>     public void detach() {}
> }
>
> I use it with a dataview on the following panel
>
> package main.java.web.components.browser;
>
> import main.java.domain.publication.IPublication;
> import main.java.domain.user.IUser;
> import main.java.services.publication.IBrowseService;
> import main.java.web.components.content.BasicPanel;
>
> import org.apache.wicket.ajax.AjaxRequestTarget;
> import
> org.apache.wicket.ajax.markup.html.navigation.paging.AjaxPagingNavigator;
> import
> org.apache.wicket.extensions.ajax.markup.html.repeater.data.sort.AjaxFallbackOrderByLink;
> import org.apache.wicket.markup.html.WebMarkupContainer;
> import org.apache.wicket.markup.html.basic.Label;
> import org.apache.wicket.markup.html.link.Link;
> import org.apache.wicket.markup.html.list.ListItem;
> import org.apache.wicket.markup.html.list.ListView;
> import org.apache.wicket.markup.repeater.Item;
> import org.apache.wicket.markup.repeater.data.DataView;
> import org.apache.wicket.model.IModel;
> import org.apache.wicket.model.LoadableDetachableModel;
> import org.apache.wicket.spring.injection.annot.SpringBean;
>
> public class BrowsePanel extends BasicPanel {
>    @SpringBean
>    IBrowseService browseService;
>
>    transient IPublication publication;
>
>    public BrowsePanel(Class<?> type) {
>        super("block", "Browse Publications");
>        setOutputMarkupId(true);
>
>        final WebMarkupContainer dataContainer = new
> WebMarkupContainer("dataContainer");
>        dataContainer.setOutputMarkupId(true);
>        add(dataContainer);
>
>        PublicationDataProvider pdp = new
> PublicationDataProvider(browseService, type);
>        final DataView dataView = new DataView("publication", pdp, 10) {
>            @Override
>            protected void populateItem(Item item) {
>                publication = (IPublication) item.getModelObject();
>                item.add(new Label("number", "" + (getCurrentPage() * 10 +
> item.getIndex() + 1)));
>                item.add(new Label("title", publication.getTitle()));
>
>                IModel authorsModel = new LoadableDetachableModel() {
>                    @Override
>                    protected Object load() {
>                        return publication.getAuthorsInOrder();
>                    }
>                };
>
>                ListView authorsListView = new ListView("author",
> authorsModel) {
>                    @Override
>                    protected void populateItem(ListItem item) {
>                        Object author = item.getModelObject();
>                        Link authorLink = new Link("authorLink") {
>                            @Override
>                            public void onClick() {
>
>                            }
>                        };
>                        if (author instanceof IUser) {
>                            authorLink.add(new Label("authorName", ((IUser)
> author).getFullName()));
>                        }
>                        else {
>                            authorLink.add(new Label("authorName",
> author.toString()));
>                            authorLink.setEnabled(false);
>                        }
>                        item.add(authorLink);
>                    }
>                };
>                item.add(authorsListView);
>                item.add(new Label("abstract",
> publication.getAbstractText()));
>            }
>        };
>
>        dataContainer.add(new AjaxFallbackOrderByLink("orderByTitle",
> "title", pdp) {
>            @Override
>            protected void onSortChanged() {
>                dataView.setCurrentPage(0);
>            }
>
>            @Override
>            protected void onAjaxClick(AjaxRequestTarget target) {
>                target.addComponent(dataContainer);
>            }
>        });
>
>        dataContainer.add(dataView);
>
>        AjaxPagingNavigator pager = new AjaxPagingNavigator("pager",
> dataView) {
>            @Override
>            protected void onAjaxEvent(AjaxRequestTarget target) {
>                target.addComponent(dataContainer);
>            }
>        };
>
>        dataContainer.add(pager);
>    }
> }
>
> when the publication instance variable wasn't transient i would get a wicket
> not serializable exception on this field. I've been reading in the forum and
> i now know that this is because the loadable detachable model that gets the
> list of user objects holds a reference to the publication, (return
> publication.getAuthorsInOrder()). transient does solve my problem, however i
> have a feeling that something is not right. Is there any elegant way to do
> this? Also i'd like to point out that all my domain objects don't implement
> the serializable interface and that they implement the IDomainObject
> interface that has only a getId() method. I've seen the IDomainObject
> interface in WIA and it implements the serializable interface. but isn't
> that against the idea of the loadable detachable model?
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org