Hi

When I use an AjaxLink and it's onClick event is called, it seems that none
of the components of the page that the AjaxLink is on has its attach/detach
model methods called.
Here is an example (I just made this quickly and roughly in order to
demonstrate the issue):

-------------

package com.company.web.wicket.pages;

import java.util.List;

import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.company.web.dao.AccountManager;
import com.company.web.dao.UsageLogManager;
import com.company.web.domain.UsageLog;

@SuppressWarnings("serial")
public class HibernateTestPage extends ExternalPage
{
    private static final Logger logger =
LoggerFactory.getLogger(HibernateTestPage.class);


    @SpringBean
    protected AccountManager accountManager;

    @SpringBean
    private UsageLogManager usageLogManager;

    @SpringBean
    private SessionFactory sessionFactory;

    protected class HibernateLoadableDetachableModel extends
LoadableDetachableModel
    {
        @Override
        protected Object load()
        {
            logger.debug("Loading usageLogs...");

            List<UsageLog> usageLogs =
usageLogManager.getUsageLogs(accountManager.findById(1));

            return usageLogs;
        }
    }


    public HibernateTestPage()
    {
        final WebMarkupContainer container = new
WebMarkupContainer("container");

        final ListView listView = new ListView("logsView",new
HibernateLoadableDetachableModel())
        {
            @Override
            protected void populateItem(ListItem listItem)
            {

                final UsageLog usageLog = (UsageLog)
listItem.getModelObject();

                Session session = sessionFactory.getCurrentSession();

                logger.debug("usageLog in populate item is in hibernate
session?" + session.contains(usageLog) );

                Label ipAddress = new
Label("ipAddress",usageLog.getIpAddress());
                listItem.add(ipAddress);

                Label outcome = new
Label("outcome",usageLog.getOutcome().toString());
                listItem.add(outcome);

                Label outcomeMsg = new
Label("outcomeMsg",usageLog.getOutcomeMsg());
                listItem.add(outcomeMsg);

                AjaxLink checkLink = new AjaxLink("checkHibernateLink")
                {
                    @Override
                    public void onClick(AjaxRequestTarget target)
                    {
                        Session session =
sessionFactory.getCurrentSession();

                        logger.debug("usageLog in checkLink is in hibernate
session?" + session.contains(usageLog) );


                    }
                };

                listItem.add(checkLink);
            }
        };

        add(container);
        container.add(listView);


    }
}

-------------

The output when the page is first accessed prints:

Loading usageLogs...
usageLog in populate item is in hibernate session? true   # For each item


However, When the checkLink is clicked it prints

usageLog in checkLink is in hibernate session? false


The logs show that the ListView's model is not loaded when the checkLink is
clicked.

I always thought that when a page is accessed by a request that all the
components are told to attach their model at the start of the request. This
does not seem to be the case. I have read
all the available request lifecycle documentation I have found but still
have not found why the model is not loaded for the page's components on an
AjaxLink click.

Can anyone explain this behavior and maybe give me a bit more detail how the
request lifecycle and the component model's work together.

If I add target.addComponent(container) in the onClick method of checkLink
the model for the ListView is loaded and populateItem is called again, with
printing true for "in hibernate session". But I need to be able to access
the attached instance of the hibernate object in the AjaxLink's onClick
method. What is the best way to achieve this?

Thanks

Reply via email to