In case anyone else ends up with a similar error, here's the solution I
ended up using. (Yes, I'm sure it's an awful hack, but right now it works
for me.)
First, I swapped the Set/List implementation I was using in Employer Info
[1], since I realized that the items affected in my previously generated
List weren't getting passed back to the Set. Then I passed my ListView the
list directly, rather than wrapped in a model [2]. The AjaxSubmitLink adds
to that list, by way of the ListView's model [3]. Then, when the user wanted
to save the updated List, I had to explicitly re-set it in the Form model
[4].
That resolved my IndexOutOfBoundsException issue. However, when I tried to
persist the list, I got an org.hibernate.NonUniqueObjectException. This is
my first Hibernate/Wicket project, so I'm pretty clueless about that one.
Searching the list, I found a post by Eelco [5] that mentioned using
Hibernate's Session.evict(), so I implemented that in the persist function
of the DAO [6]. Now it appears to be working!
------
[1] - public class EmployerInfo extends PersonInfoImpl {
...
List<ContactPoint> contactPointsList;
public List<ContactPoint> getContactPoints() {
return contactPointsList;
}
public void setContactPoints(List<ContactPoint> contactPointsList) {
this.contactPointsList = contactPointsList;
}
public Set<ContactPoint> getContactPointsSet() {
return new HashSet<ContactPoint>(contactPointsList);
}
public void setContactPointsSet(Set<ContactPoint> contactPointsSet) {
List<ContactPoint> list = new
ArrayList<ContactPoint>(contactPointsSet);
Collections.sort(list);
contactPointsList = list;
}
}
[2] - final ListView<ContactPoint> contactPointsListView = new
ListView<ContactPoint>("contactPoints",
employerInfoModel.getObject().getContactPoints()) {...};
[3] - new AjaxSubmitLink("addContactLink", this) {
@Override
public void onSubmit(AjaxRequestTarget target, Form<?> form)
{
contactPointsListView.getModelObject().add(new
ContactPointImpl());
target.addComponent(contactPointsContainer);
}
[4] - new SubmitLink("saveContactPoints") {
@Override
public void onSubmit() {
super.onSubmit();
employerInfoModel.getObject().setContactPoints(contactPointsListView.getModelObject());
personInfoDao.persistOrMerge(employerInfoModel.getObject());
info("Your account has been updated.");
}
[5] - http://www.nabble.com/delete-onSubmit-td22839614.html#a22839614
[6] - public void persistOrMerge(PersonInfo personInfo) {
getHibernateTemplate().evict(personInfo);
try {
getHibernateTemplate().saveOrUpdate(personInfo);
} catch (Exception e) {
getHibernateTemplate().merge(personInfo);
}
}