Skip to main content

can't update h:dataTable with List as value

10 replies [Last post]
chrisouellette
Offline
Joined: 2009-03-03

Hi,

I have an h:datatable which is bound to a List object in my bean class. I want the datatable to display a list of inputs which will allow the user to update these String values.

My problem is that my bean is not accepting the user's updates. If I create a new object to hold the String (i.e. StringWrapper), and I attach my data table to a List, I get the functionality I want. But do I really have to resort to this?

Any input or ideas appreciated. Thanks.

Here is my code:

Facelet:

Backing Bean:
public class TestObj implements Serializable {

private static final long serialVersionUID = 0x066E639ED3098D82L;

private List people = new ArrayList();
private List names = new ArrayList();

public TestObject() {
people.add(new Person());
names.add(new String());
}

public List getList() {
return people;
}

public String addPerson() {
people.add(new Person());
return null;
}

public List getNames() {
return names;
}

public String addName() {
names.add(new String());
return null;
}

public class Person implements Serializable {

private static final long serialVersionUID = 1L;

private String firstname;
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}

}
}

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
chrisouellette
Offline
Joined: 2009-03-03

> No property is specified (i.e. name.
).
>
> From the javadocs of ELResolver.setValue():
> Attempts to set the value of the given property
> object on the given
> ase object.
>
> So, what exactly is going to be set on the #{name}
> object?
>

Thanks for responding, Ryan. This is starting to make more sense. My problem with this is that while the inputText isn't specifying a property, #{name} is a variable passed in from the parent element. If the is bound to an object and a property (#{testObj.names}, a List object) shouldn't the variable that the dataTable creates be updatable?

Ryan Lubke

On 3/5/09 6:51 PM, webtier@javadesktop.org wrote:
>> No property is specified (i.e. name.
).
>>
>> From the javadocs of ELResolver.setValue():
>> Attempts to set the value of the given property
>> object on the given
>> ase object.
>>
>> So, what exactly is going to be set on the #{name}
>> object?
>>
>>
>
> Thanks for responding, Ryan. This is starting to make more sense. My problem with this is that while the inputText isn't specifying a property, #{name} is a variable passed in from the parent element. If the is bound to an object and a property (#{testObj.names}, a List object) shouldn't the variable that the dataTable creates be updatable?
>
The DataModel that wraps your List provides no provision for updating
the underlying collection itself.
If upates are required, the model object will need to expose the
appropriate methods to do so.
> [Message sent by forum member 'chrisouellette' (chrisouellette)]
>
> http://forums.java.net/jive/thread.jspa?messageID=335447
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: webtier-unsubscribe@glassfish.dev.java.net
> For additional commands, e-mail: webtier-help@glassfish.dev.java.net
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: webtier-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: webtier-help@glassfish.dev.java.net

Ryan Lubke

On 3/3/09 9:42 PM, Lincoln Baxter, III wrote:
> This seems like an implementation issue/shortcoming. It seems logical
> to me that despite String being immutable, it should still be a
> functional dataTable value... the fact that java.lang.String is
> immutable should not affect the behavior of the DataTable.... Just
> have the table create a new string...
I don't see this as an issue with UIData.

From the provided example:
-------------------------------------


...

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

No property is specified (i.e. name.
).

From the javadocs of ELResolver.setValue():

Attempts to set the value of the given property object on the given
base object.

So, what exactly is going to be set on the #{name} object?

>
> Thoughts?
>
> On Tue, 2009-03-03 at 22:35 -0700, Joel Weight wrote:
>> You can't "update" a string because String objects are immutable.
>> This is why it works with your StringWrapper and not with String.
>> I'm a relative newbie with facelets, but I'm guessing you'll have to
>> use some object ( as you already surmised with your StringWrapper )
>> that has a String property that you can modify instead of changing
>> the object itself like you are with a List and value="#{name}
>>
>> Joel
>>
>> On Tue, Mar 3, 2009 at 2:44 PM, >> > wrote:
>>
>> Hi,
>>
>> I have an h:datatable which is bound to a List object in
>> my bean class. I want the datatable to display a list of inputs
>> which will allow the user to update these String values.
>>
>> My problem is that my bean is not accepting the user's updates.
>> If I create a new object to hold the String (i.e. StringWrapper),
>> and I attach my data table to a List, I get the
>> functionality I want. But do I really have to resort to this?
>>
>> Any input or ideas appreciated. Thanks.
>>
>> Here is my code:
>>
>> [b]Facelet:[/b]
>> >> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
>> >> xmlns:h="http://java.sun.com/jsf/html"
>> xmlns:a4j="http://richfaces.org/a4j"
>> xmlns:f="http://java.sun.com/jsf/core">
>>
>>
>>
>>
>>

>>
>>
>>
>>
>>
>>

>>

>>

>>
>>
>>

>>

>>

>>
>>
>>
>>
>>
>>

>>

>>

>>
>>
>>

>>

>>
>>
>>
>>
>> [b]Backing Bean:[/b]
>> public class TestObj implements Serializable {
>>
>> private static final long serialVersionUID = 0x066E639ED3098D82L;
>>
>> private List people = new ArrayList();
>> private List names = new ArrayList();
>>
>> public TestObject() {
>> people.add(new Person());
>> names.add(new String());
>> }
>>
>> public List getList() {
>> return people;
>> }
>>
>> public String addPerson() {
>> people.add(new Person());
>> return null;
>> }
>>
>> public List getNames() {
>> return names;
>> }
>>
>> public String addName() {
>> names.add(new String());
>> return null;
>> }
>>
>> public class Person implements Serializable {
>>
>> private static final long serialVersionUID = 1L;
>>
>> private String firstname;
>> public String getFirstname() {
>> return firstname;
>> }
>> public void setFirstname(String firstname) {
>> this.firstname = firstname;
>> }
>>
>> }
>> }
>> [Message sent by forum member 'chrisouellette' (chrisouellette)]
>>
>> http://forums.java.net/jive/thread.jspa?messageID=334921
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail:
>> webtier-unsubscribe@glassfish.dev.java.net
>>
>> For additional commands, e-mail:
>> webtier-help@glassfish.dev.java.net
>>
>>
>>

---------------------------------------------------------------------
To unsubscribe, e-mail: webtier-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: webtier-help@glassfish.dev.java.net

Lincoln Baxter, III

On Thu, 2009-03-05 at 11:59 -0800, Ryan Lubke wrote:

> No property is specified (i.e. name.
).
>
> From the javadocs of ELResolver.setValue():
>
> Attempts to set the value of the given property object on the
> given
> base object.
>
> So, what exactly is going to be set on the #{name} object?

A new String object, if it has changed, unless I'm missing something
here.
[att1.html]

Ryan Lubke

On 3/5/09 6:27 PM, Lincoln Baxter, III wrote:
> On Thu, 2009-03-05 at 11:59 -0800, Ryan Lubke wrote:
>> No property is specified (i.e. name.
).
>>
>> From the javadocs of ELResolver.setValue():
>>
>> Attempts to set the value of the given property object on the given
>> base object.
>>
>> So, what exactly is going to be set on the #{name} object?
>
> A new String object, if it has changed, unless I'm missing something
> here.
And set it into what? Based on ELResolver.setValue() we need both a base
and a property. The expression #{name} provides only the base.

---------------------------------------------------------------------
To unsubscribe, e-mail: webtier-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: webtier-help@glassfish.dev.java.net

Lincoln Baxter, III

Ahh, I understand. That's unfortunate. In that case, it is certainly a
limitation of ElResolver ;) and could still be enhanced.

Is this even worth considering? It would improve this particular use
case, but what else would it impact?

On Thu, 2009-03-05 at 18:33 -0800, Ryan Lubke wrote:

> On 3/5/09 6:27 PM, Lincoln Baxter, III wrote:
> > On Thu, 2009-03-05 at 11:59 -0800, Ryan Lubke wrote:
> >> No property is specified (i.e. name.
).
> >>
> >> From the javadocs of ELResolver.setValue():
> >>
> >> Attempts to set the value of the given property object on the given
> >> base object.
> >>
> >> So, what exactly is going to be set on the #{name} object?
> >
> > A new String object, if it has changed, unless I'm missing something
> > here.
> And set it into what? Based on ELResolver.setValue() we need both a base
> and a property. The expression #{name} provides only the base.
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: webtier-unsubscribe@glassfish.dev.java.net
> For additional commands, e-mail: webtier-help@glassfish.dev.java.net
>
[att1.html]

Ryan Lubke

On 3/5/09 6:41 PM, Lincoln Baxter, III wrote:
> Ahh, I understand. That's unfortunate. In that case, it is certainly a
> limitation of ElResolver ;) and could still be enhanced.
>
> Is this even worth considering? It would improve this particular use
> case, but what else would it impact?
If it's bothering someone that much, they could always write their own
ELResolver to do what the need.
I really see this as a corner case myself, but what do I know ;)
>
> On Thu, 2009-03-05 at 18:33 -0800, Ryan Lubke wrote:
>> On 3/5/09 6:27 PM, Lincoln Baxter, III wrote:
>> > On Thu, 2009-03-05 at 11:59 -0800, Ryan Lubke wrote:
>> >> No property is specified (i.e. name.
).
>> >>
>> >> From the javadocs of ELResolver.setValue():
>> >>
>> >> Attempts to set the value of the given property object on the given
>> >> base object.
>> >>
>> >> So, what exactly is going to be set on the #{name} object?
>> >
>> > A new String object, if it has changed, unless I'm missing something
>> > here.
>> And set it into what? Based on ELResolver.setValue() we need both a base
>> and a property. The expression #{name} provides only the base.
>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail:webtier-unsubscribe@glassfish.dev.java.net
>> For additional commands, e-mail:webtier-help@glassfish.dev.java.net
>>
>>

---------------------------------------------------------------------
To unsubscribe, e-mail: webtier-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: webtier-help@glassfish.dev.java.net

Joel Weight

You can't "update" a string because String objects are immutable. This is
why it works with your StringWrapper and not with String. I'm a relative
newbie with facelets, but I'm guessing you'll have to use some object ( as
you already surmised with your StringWrapper ) that has a String property
that you can modify instead of changing the object itself like you are with
a List and value="#{name}

Joel

On Tue, Mar 3, 2009 at 2:44 PM, wrote:

> Hi,
>
> I have an h:datatable which is bound to a List object in my bean
> class. I want the datatable to display a list of inputs which will allow the
> user to update these String values.
>
> My problem is that my bean is not accepting the user's updates. If I create
> a new object to hold the String (i.e. StringWrapper), and I attach my data
> table to a List, I get the functionality I want. But do I
> really have to resort to this?
>
> Any input or ideas appreciated. Thanks.
>
> Here is my code:
>
> [b]Facelet:[/b]
> > http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
> > xmlns:h="http://java.sun.com/jsf/html"
> xmlns:a4j="http://richfaces.org/a4j"
> xmlns:f="http://java.sun.com/jsf/core">
>
>
>
>
>

>
> > var="person">
>
>
> > reRender="rows" />
>

>

>

>
> > action="#{testObj.addPerson}" />
>

>

>

>
>
>
>
> > reRender="names" />
>

>

>

>
> > action="#{testObj.addName}" />
>

>

>
>
>
>
> [b]Backing Bean:[/b]
> public class TestObj implements Serializable {
>
> private static final long serialVersionUID = 0x066E639ED3098D82L;
>
> private List people = new ArrayList();
> private List names = new ArrayList();
>
> public TestObject() {
> people.add(new Person());
> names.add(new String());
> }
>
> public List getList() {
> return people;
> }
>
> public String addPerson() {
> people.add(new Person());
> return null;
> }
>
> public List getNames() {
> return names;
> }
>
> public String addName() {
> names.add(new String());
> return null;
> }
>
> public class Person implements Serializable {
>
> private static final long serialVersionUID = 1L;
>
> private String firstname;
> public String getFirstname() {
> return firstname;
> }
> public void setFirstname(String firstname) {
> this.firstname = firstname;
> }
>
> }
> }
> [Message sent by forum member 'chrisouellette' (chrisouellette)]
>
> http://forums.java.net/jive/thread.jspa?messageID=334921
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: webtier-unsubscribe@glassfish.dev.java.net
> For additional commands, e-mail: webtier-help@glassfish.dev.java.net
>
>
[att1.html]

Lincoln Baxter, III

This seems like an implementation issue/shortcoming. It seems logical to
me that despite String being immutable, it should still be a functional
dataTable value... the fact that java.lang.String is immutable should
not affect the behavior of the DataTable.... Just have the table create
a new string...

Thoughts?

On Tue, 2009-03-03 at 22:35 -0700, Joel Weight wrote:

> You can't "update" a string because String objects are immutable.
> This is why it works with your StringWrapper and not with String. I'm
> a relative newbie with facelets, but I'm guessing you'll have to use
> some object ( as you already surmised with your StringWrapper ) that
> has a String property that you can modify instead of changing the
> object itself like you are with a List and value="#{name}
>
> Joel
>
>
> On Tue, Mar 3, 2009 at 2:44 PM, wrote:
>
> Hi,
>
> I have an h:datatable which is bound to a List object
> in my bean class. I want the datatable to display a list of
> inputs which will allow the user to update these String
> values.
>
> My problem is that my bean is not accepting the user's
> updates. If I create a new object to hold the String (i.e.
> StringWrapper), and I attach my data table to a
> List, I get the functionality I want. But do I
> really have to resort to this?
>
> Any input or ideas appreciated. Thanks.
>
> Here is my code:
>
> [b]Facelet:[/b]
> > "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
> > xmlns:h="http://java.sun.com/jsf/html"
> xmlns:a4j="http://richfaces.org/a4j"
> xmlns:f="http://java.sun.com/jsf/core">
>
>
>
>
>

>
> > value="#{testObj.list}" var="person">
>
> > value="#{person.firstname}">
> > event="onchange" reRender="rows" />
>
>

>

>
> > action="#{testObj.addPerson}" />
>

>

>

>
> > value="#{testObj.names}" var="name">
>
>
> > event="onchange" reRender="names" />
>

>

>

>
> > action="#{testObj.addName}" />
>

>

>
>
>
>
> [b]Backing Bean:[/b]
> public class TestObj implements Serializable {
>
> private static final long serialVersionUID =
> 0x066E639ED3098D82L;
>
> private List people = new ArrayList();
> private List names = new ArrayList();
>
> public TestObject() {
> people.add(new Person());
> names.add(new String());
> }
>
> public List getList() {
> return people;
> }
>
> public String addPerson() {
> people.add(new Person());
> return null;
> }
>
> public List getNames() {
> return names;
> }
>
> public String addName() {
> names.add(new String());
> return null;
> }
>
> public class Person implements Serializable {
>
> private static final long serialVersionUID = 1L;
>
> private String firstname;
> public String getFirstname() {
> return firstname;
> }
> public void setFirstname(String firstname) {
> this.firstname = firstname;
> }
>
> }
> }
> [Message sent by forum member
> 'chrisouellette' (chrisouellette)]
>
> http://forums.java.net/jive/thread.jspa?messageID=334921
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail:
> webtier-unsubscribe@glassfish.dev.java.net
> For additional commands, e-mail:
> webtier-help@glassfish.dev.java.net
>
>
>
[att1.html]

chrisouellette
Offline
Joined: 2009-03-03

Joel and Lincoln, thanks for your input.

It's good to know that the problem can be explained because of String's immutability but I agree with Lincoln that this seems like a shortcoming with JSF or Mojarra. I have another case in the same application where I want to modify a list of Long's but I will have to implement the same wrapper logic there as well.

Also, does anyone know where this type of detail would be documented? Could I figure it out by looking at the source code for dataTable?

Thanks again,

-Chris