Getters being called multiple times is in some way a consequence of the JSF
pull model.

And to be really honest, I also often put data access inside a getter (often
the easiest option), but there are some other options.

- If you're using JSF 1.2, you can use the @PostConstruct annotation to
indicate a method that has to be called when the bean is created (after the
constructor and after dependency injection). Without JSF 1.2, you can create
behavior like this, for example by creating your own VariableResolver, but
this may be overkill for your problem.

- You can also use an action listener to load data into a member. This
option is very explicit, since you know exactly when the method will be
called, but it sometimes doesn't work, since the action listener isn't
called when you access the page directly. So you always need to get to your
page through a commandButton/commandLink. When using a request scoped
managed bean to store your data, this mechanism isn't very reliable, because
when you refresh or press a button on the page itself, the request scoped
data is lost and you have to find a way to re-initialize it. It also only
works when you use forwards, not with redirects, since you lose your request
scoped data with the redirect.

- A third option is using a library like Shale or Seam, which provide View
Controller like behavior. This means that you can attach a method to your
page. This method will be called with each page request, giving you a hook
to load your data. http://shale.apache.org/shale-view/index.html

- But IMHO the easiest option is this one:
public class RequestScopedBean {
    private SimpleScheduleModel model;
    public SimpleScheduleModel getModel() {
        if (model == null) {
            loadData();
        }
        return model;
    }
}

I don't know the context of the system, but if you want a simple solution in
a JSF 1.1 environment, just use the last one, otherwise the first one. When
you see yourself writing data access logic inside getters, consider one of
the other options. I've seen JSF applications become totally unmaintainable
because people use constructs like these all the time instead of fixing the
problem.

Regards,

Jan-Kees

Ps. Seam has an annotation for people who get tired of those null checks:
http://docs.jboss.org/seam/2.0.2.GA/reference/en-US/html/tutorial.html#d0e977
You can see the data access logic inside a separate method, which get called
when you try to resolve the variable "messageList" and it is not initialized
yet.



2008/9/19 Daniel S. Teixeira <[EMAIL PROTECTED]>

> Hi Jan.
> Thanks for your answer... That helps a lot.
>
> So, I would like to know where should be the better place to fill the model
> object with entries...
> Imagine something like this:
> I have some entries per day.. So, my scheduele view will be show by day
> (ScheduleModel.DAY). By default, I want to fill the schedule at the first
> time with data from the current day...
> So, I need to get entries (in this case, from database).
>
> On my service layer: someService.findByDay(Date day) - this method return
> all messages from my database.
>
> So, where should I call it?
> I'm little bit confuse...
>
> Thanks in advance,
> Daniel
>
>
> 2008/9/19 Jan-Kees van Andel <[EMAIL PROTECTED]>
>
> I don't see what the problem is. Components call getters all the time.
>> Normally this is no problem since there should not be logic in the getter.
>> But your solution is not uncommon.
>>
>> So, the model.isEmpty protects the loadData to be called multiple times.
>> Two things:
>> 1 Are you sure you update your model attribute within loadData()? If not,
>> it's no surprise loadData gets called, since it remains empty. :)
>> 2 When loadData loads an empty model, model.isEmpty() will always return
>> true, even if called multiple times.
>>
>> I think the easiest thing to do (if what I'm describing is really your
>> problem) is replacing the isEmpty check with a "model == null" check, which
>> is more reliable, because it can deal with empty models. Also, it is more
>> fail-fast, instead of lurking in your code until the stars line up.
>>
>> But a getter being called multiple times within a single request is not
>> uncommon. If you want to do stuff inside the getter, just protect the code
>> with a check like the null check I said before.
>>
>> Hope this helps.
>>
>> Regards,
>>
>> Jan-Kees
>>
>>
>> 2008/9/19 Daniel S. Teixeira <[EMAIL PROTECTED]>
>>
>> Hi,
>>> I'm trying to use Schedule component.
>>> I need to load some values from database in order to fill the schedule.
>>> On my backing bean I have 1 private atributte called model (with get/set
>>> methods).
>>> When the page is called, for some reason the getModel method is called a
>>> lot of times... More than 100 times.
>>> Is this a normal behavior?
>>>
>>> Cause I wanted to load data from getModel method like:
>>>
>>> public SimpleScheduleModel getModel() {
>>>     if (model.isEmpty())
>>>         loadData();
>>>     return model;
>>> }
>>>
>>> I don't really know if I'm doing something wrong...
>>>
>>> Baking bean scope: request
>>>
>>> Regards,
>>>
>>>
>>> --
>>> Daniel S. Teixeira
>>> [EMAIL PROTECTED]
>>>
>>
>>
>
>
> --
> Daniel S. Teixeira
> [EMAIL PROTECTED]
>

Reply via email to