Ajax request and lifecycle of model attach/detach

2009-05-27 Thread Wilter du Toit
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...);

ListUsageLog 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


Re: Ajax request and lifecycle of model attach/detach

2009-05-27 Thread Igor Vaynberg
models are loaded lazily, eg imodel does not have an attach(), only a
detach(). so unless your link accesses the model - eg invokes
getobject() on it nothing will be loaded. at the end of request all
models should get detach() called.

-igor

On Wed, May 27, 2009 at 2:30 AM, Wilter du Toit wpdut...@gmail.com wrote:
 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...);

            ListUsageLog 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


-
To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org
For