Hello, I'm having some difficulties with the AjaxFormLoop component and I'm
hoping one of you guys could help me out.


For the most part, I've followed the following example
http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/AjaxFormLoop.htmlhowever,
my implementation needs to be slightly different from the
example.

I need to be able to instantiate a new Person() object and before ever
persisting the object be able to add new Phone objects to the arraylist
with the ajaxformloop. Once the user finishes inputting the data, then save
the changes by submitting the form and commit them all to the database.

Now I'm aware you need to use a value encoder to do this, but I'm running
into an issue where hibernate is trying to save the phone object before I
ever call session.save() which is resulting exceptions.

I'm hoping someone can provide me with a little help or an example of how
to accomplish this task.

Example code

<div t:type="ajaxformloop" t:id="phones" source="person.phones"
value="phone" encoder="encoder">
    <t:textfield t:id="number" value="phone.number"/>
    <t:removerowlink>remove</t:removerowlink>
</div>

public class Edit {

  @PageActivationContext
  @Property
  private Person person;

  @Property
  private Phone phone;

  @Inject
  private Session session;

  public void onPrepare() {
      if(person == null) {
          person = new Person();
      }
  }

  @CommitAfter
  public Object onSuccess() {
      session.saveOrUpdate(person);
      return Index.class;
  }

  Object onAddRowFromPhones() {
      return new Phone();
  }

  @CommitAfter
  void onRemoveRowFromPhones(Phone phone) {
      if(phone.getId() != null) {
          session.delete(phone);
      }
  }

  @SuppressWarnings("unchecked")
  public ValueEncoder getEncoder() {
     return new ValueEncoder<AccessPoint>() {

            @Override
            public String toClient(Phone value) {
                Long id = value.getId();
                return id != null ? id.toString() : null;
            }

            @Override
            public Phone toValue(String toValue) {
                if(toValue != null) {
                    System.out.println(toValue);
                    Long id = Long.parseLong(toValue);
                    phone = session.createCritera(Phone.class, id);
                } else {
                    person.getPhones().add(phone);
                    phone = new Phone(person);
                }
                return phone;
            }
        };
    }
}

@Entity
public class Person {

    @Id
    @GeneratedValue(strategy = GenerationType.auto)
    @NonVisual
    private long id;

    @OneToMany(mappedBy = "person", cascade = CascadeType.ALL,
orphanRemoval = true)
    private List<Phone> phones;

    public List<Phone> getPhones() {
        if(phones == null) {
            phones = new ArrayList<>();
        }
        return phones;
    }

    public void setPhones(List<Phone> phones) {
        this.phones = phones;
    }

}

@Entity
public class Phone {

    @Id
    @GeneratedValue(strategy = GenerationType.auto)
    @NonVisual
    private long id;

    @ManyToOne(optional = false)
    private Person person;

    @Column(nullable = true, length = 20)
    @Width(20)
    @Validate("required,maxlength=20")
    private String number;

    public Phone(Person person) {
        this.person = person;
    }

    //getters and setters

}

Thanks in advance.

Reply via email to