On Wed, Aug 5, 2009 at 1:34 PM, Troy Cauble<troycau...@gmail.com> wrote:
> Thanks very much.  I have some follow up questions below, please....
>
> On Wed, Aug 5, 2009 at 2:22 PM, Igor Vaynberg<igor.vaynb...@gmail.com> wrote:
>> to start: the core problem is how does wicket identify which row you
>> clicked in a listview? the url contains the component path of the link
>> you clicked. a listview item only keeps the index of the element in
>> the list, so when you click that link the sequence is
>>
>> link.getmodel()->listitem_the_link_is_in.getmodel()->listview.getmodel().get(listitem.index)
>>
>> listviews are for lists. a list is a collection where elements are
>> uniquely identified by their index - ie the PK of a list entry is its
>> index.
>>
>> for a collection of elements backed by a list it is fine to use ListView.
>>
>> lets look at your code:
>>
>> @org.hibernate.annotations.CollectionOfElements
>> private Collection<User> users = new ArrayList<User>();
>>
>> this is not a list - this is a collection. what will hibernate use to
>> back this when it loads? will it still be a List or a Set?
>
> For Hibernate this is a (small) collection of items.  I'm not
> (intentionally) doing anything that relies on Hibernate backing
> it with a List internally.

exactly, this is not a list so you cannot rely on the index
identifying the element - so do not use a listview.

> Also, I was trying to not let the UI drive the database schema.
> I was using ListView::setList(new ArrayList<"User">(users)).
>
> In theory, that can have a different order with every new ArrayList,
> so I should do something sorted.  But this is a small list I can
> sort after loading, must I have an index in the db?

if you sort the items based on some criteria then you should be ok
without an index column, as long as the order is always the same.

>> for such a mapping you cannot use a listview because the order in
>> which these elements are loaded is not guaranteed and so this is not a
>> list. what this means is that you render the list, click a link in the
>> third row - but when wicket will try to load the third element from
>> the list it is no longer guaranteed to be the same - so it will load
>> the wrong one - very bad. eg user clicks to delete user "bob" but
>> deletes user "jon" instead.
>
> I think I understanding this.  My delete Button has a reference
> to the User, so that shouldn't get lost.

how does it have that?

> I guess this "wrong element" problem
> happens before my button is even identified?  Is it that a model reload makes
> the server side data different from the client and the wrong button is found?

the correct button is always found, the problem is that if the model
of the button depends on the model of the listview - eg the button's
model is the third element in the list and the list backing the
listview is actually a set with a different ordering loaded every
time, then the "third element" is not stable - every request it can be
something different.

so you render the page that has ordering {a,b,c}, the user clicks the
delete link on {a} - element zero. this creates a different request to
the server and now the list is loaded in order {c,a,b}. the button
still remembers it has to delete element zero, so it delets {c} from
the list instead of {a}.

>> now, not sure if this works with collectionofelements, but if you did
>> something like this:
>> @org.hibernate.annotations.CollectionOfElements
>> @org.hibernate.annotations.IndexColumn(name="idx")
>> private List<User> users = new ArrayList<User>();
>>
>> then this would be a list and you could use a listview with this.
>> however, because of the concurrent nature of the web you should always
>> use optimistic locking when working with lists.
>
> OK, I think.  I am writing the HIbby POJOs and schema, so I can add a
> column if I have to.  But what's the solution with a legacy schema?
> How do we use something in the RepeatingView family to present a
> collection of value types without primary keys?
>
> (I guess a value type has a composite key?...)

if there trully is no PK for the items in that collection then you
should always sort them and use optimistic locking on the parent
entity. it doesnt matter what framework you work with, this is
universal for a web environment.

> Also, if we're worried about Java List indexes being invalid, is a db
> IndexColumn
> a sufficient substitute for a PK?

yes, the db index column will ensure that the java list ordering is
always the same.

>> if you have a @OneToMany then you should not use a listview because,
>> once again, the elements returned are not a true list - each entry has
>> its own PK and does not use it's index in the list as the PK. for that
>> you should use a dataview and return a model that can load the entity
>> by its true PK.
>
> OK.  Since they have keys, it's better to wrap a model around each entity.
> But in terms of loading the list of entities in the IDataProvider
> implementation,
> should I go to the database "again" or can I reference the list/whatever on 
> the
> Foo instance that I'm already loading from the database?

you dont need to go to the database again because
idataprovider.model(entity) gives you the entity itself which you can
wrap in the model and so for that request since the model already has
the object there is no second trip. go to wicketinaction.com and look
up an article i wrote about "smart entity models"

-igor

>
> THANK YOU.
> -troy
>
>
>>
>> -igor
>>
>> On Wed, Aug 5, 2009 at 11:02 AM, Troy Cauble<troycau...@gmail.com> wrote:
>>> Short version:
>>> What's the right way to View & Model lists of Hibernate data that
>>> are not Entities (@CollectionsOfElements) and already loaded via
>>> an Entity?
>>>
>>> What if they are Entities, but are already loaded via another Entity
>>> (@OneToMany)?
>>>
>>> Long version:
>>> Absorbing the mantra "ListView is bad for database data", I was looking into
>>> converting some ListViews into DataViews.  But these list items are
>>> not Hibernate
>>> Entities.  They're  CollectionsOfElements belonging to an Entity.
>>>
>>> @Entity
>>> class Foo
>>> {
>>>       �...@org.hibernate.annotations.collectionofelements
>>>        private Collection<User> users = new ArrayList<User>();
>>>        ...
>>> }
>>>
>>> So the example
>>>
>>> class UsersProvider implements IDataProvider
>>> {
>>>        public Iterator iterator(int first, int count)
>>>        {
>>>
>>> ((MyApplication)Application.get()).getUserDao().iterator(first,
>>> count);
>>>        }
>>>
>>>        public int size()
>>>        {
>>>                ((MyApplication)Application.get()).getUserDao().getCount();
>>>        }
>>>
>>>        public IModel model(Object object)
>>>        {
>>>                return new DetachableUserModel((User)object);
>>>        }
>>>  }
>>>
>>> doesn't really fit.  My "Users" are a list hanging off an Entity that is
>>> loaded from the database.  My "Users" don't have a unique ID for
>>> their own DetachableUserModel.
>>>
>>> So, should I create an IDataProvider that references the higher
>>> level Entity Foo?  Or should I stick with ListView and ::setList()
>>> (after Foo's LDM refreshes the list)?  Something else?
>>>
>>> Is the answer the same when the data *are* Entities, but are already
>>> loaded via the LDM of another Entity?
>>>
>>> @Entity
>>> class Foo
>>> {
>>>       �...@onetomany
>>>        private Set<OtherEntity> = new TreeSet<OtherEntity>();
>>>        ...
>>> }
>>>
>>> Thanks,
>>> -troy
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org
>>> For additional commands, e-mail: users-h...@wicket.apache.org
>>>
>>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org
>> For additional commands, e-mail: users-h...@wicket.apache.org
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org
> For additional commands, e-mail: users-h...@wicket.apache.org
>
>

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

Reply via email to