You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@myfaces.apache.org by "Daniel S. Teixeira" <da...@gmail.com> on 2008/09/19 22:06:26 UTC

Tomahawk Schedule: getModel() repeats

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
dansouza@gmail.com

Re: Tomahawk Schedule: getModel() repeats

Posted by "Daniel S. Teixeira" <da...@gmail.com>.
Hi Jan,
I tried the first option (with @PostConstruct) and works fine for my
application, cause I'm using JSF1.2!

Thanks,

-- 
Daniel S. Teixeira
dansouza@gmail.com

2008/9/20 Jan-Kees van Andel <ja...@gmail.com>

> 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 <da...@gmail.com>
>
>> 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 <ja...@gmail.com>
>>
>> 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 <da...@gmail.com>
>>>
>>> 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
>>>> dansouza@gmail.com
>>>>
>>>
>>>
>>
>>
>> --
>> Daniel S. Teixeira
>> dansouza@gmail.com
>>
>
>

Re: Tomahawk Schedule: getModel() repeats

Posted by Jan-Kees van Andel <ja...@gmail.com>.
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 <da...@gmail.com>

> 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 <ja...@gmail.com>
>
> 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 <da...@gmail.com>
>>
>> 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
>>> dansouza@gmail.com
>>>
>>
>>
>
>
> --
> Daniel S. Teixeira
> dansouza@gmail.com
>

Re: Tomahawk Schedule: getModel() repeats

Posted by "Daniel S. Teixeira" <da...@gmail.com>.
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 <ja...@gmail.com>

> 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 <da...@gmail.com>
>
> 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
>> dansouza@gmail.com
>>
>
>


-- 
Daniel S. Teixeira
dansouza@gmail.com

Re: Tomahawk Schedule: getModel() repeats

Posted by Jan-Kees van Andel <ja...@gmail.com>.
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 <da...@gmail.com>

> 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
> dansouza@gmail.com
>