#733 ✓invalid
Alexandre PETRILLO

Impossible to bind a collection of sub-components

Reported by Alexandre PETRILLO | April 14th, 2011 @ 09:35 AM | in 1.2.5 (closed)

Summary: Binding parameters to a POJO with a Collection of sub-components (=Entity) aren't possible.

Including a reproduction steps with a possible patch

Framework version: 1.2.RC2
Platform you're using: Windows 7

Reproduction steps:

I want to display a page with a form, to modify an "Actor" object, and in same time, his addresses. Actor is a Model, Address too, actor have a collection of addresses.
So, in my example Address is an Actor's component.

Details:

this is my models :

@Entity public class Actor extends Model {
    public String name;

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    public List<Address> addresses;

    @ManyToMany
    public List<Movie> movies;
}

@Entity public class Address extends Model {
      public String streetName;
      public String cityName;
}

@Entity public class Movie extends Model {
      public String name;
}

And I want a very simple controller action for save Actor and his addresses :

    public static void save(Actor actor) {
        actor.save();// That's All!
        index(actor.id); //redirect to show actor's page
    }

For do that, in my html page, I iterate over addresses, and when I create an input, I need to indicate the component linked with it

#{list items:actor.addresses, as:'address'}
<tr>
    <td><input type="text" name="actor.addresses@${address.id}.streetName" value="${address.streetName}"/></td>
    <td><input type="text" name="actor.addresses@${address.id}.cityName" value="${address.cityName}"/></td>
</tr>
#{/form}

I choose @ symbol to indicate id's component.

With this notation, I can MODIFY an EXISTING address.

Now I want to ADD a NEW address
for do that, I use a virtual id prefixed by "new:" like this :

<tr>
    <td><input type="text" name="actor.addresses@new:1.streetName" value=""/></td>
    <td><input type="text" name="actor.addresses@new:1.cityName" value=""/></td>
</tr>

the prefix new: indicate a virtual id. It's very essential for adding many addresses on same time :

<tr><!-- inputs to add first address -->
    <td><input type="text" name="actor.addresses@new:1.streetName" value=""/></td>
    <td><input type="text" name="actor.addresses@new:1.cityName" value=""/></td>
</tr>
<tr><!-- inputs to add 2nds address in same time -->
    <td><input type="text" name="actor.addresses@new:2.streetName" value=""/></td>
    <td><input type="text" name="actor.addresses@new:2.cityName" value=""/></td>
</tr>

Now I want to DELETE an EXISTING address
First I can create a simple link :

<a href="@{Application.removeAddress(actor.id,address.id)}">Remove by url</a>

But it would be interesting, to do that with only a POST action :

I add an hidden input with name actor.addresses.id for each address like this :

#{list items:actor.addresses, as:'address'}
<tr>
    <input type="hidden" name="actor.addresses.id" value="${address.id}"/>
    <td><input type="text" name="actor.addresses@${address.id}.streetName" value="${address.streetName}"/></td>
    <td><input type="text" name="actor.addresses@${address.id}.cityName" value="${address.cityName}"/></td>
#{/list}

And for delete an address I just create a JavaScript button to delete inputs linked to this address.

For Summary :
I can modify a component :
I can add a component :
( or ) I can delete a component by specifying all components ids :

With this technique we just need to create, delete or update input's value to bind a complex Object, with all his components.

All modifications are included in GenericModel.java, i will submit a patch next.

Comments and changes to this ticket

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.

New-ticket Create new ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

<h2>Play framework</h2>

Play makes it easier to build Web applications with Java. It is a clean alternative to bloated Enterprise Java stacks. It focuses on developer productivity and targets RESTful architectures. Learn more on the <a href="http://www.playframework.org">http://www.playframework.org</a> website.<br><br>

<h2>Source code is hosted on github</h2>Check out our repository at <a href="http://github.com/playframework/play">http://github.com/playframework/play</a><br><br>

<h2>Contributing, creating a patch</h2> Please read the <a href="http://play.lighthouseapp.com/projects/57987/contributor-guide">contributor guide</a><br><br>

<h2>Reporting Security Vulnerabilities</h2> Since all bug reports are public, please report any security vulnerability directly to <em>guillaume dot bort at gmail dot com</em>.<br><br>

<h2>Creating a bug report</h2> Bug reports are incredibly helpful, so take time to report bugs and request features in our ticket tracker. We’re always grateful for patches to Play’s code. Indeed, bug reports with attached patches will get fixed far quickly than those without any.<br><br>

Please include as much relevant information as possible including the exact framework version you're using and a code snippet that reproduces the problem.<br><br>

Don't have too much expectations. Unless the bug is really a serious "everything is broken" thing, you're creating a ticket to start a discussion. Having a patch (or a branch on Github we can pull from) is better, but then again we'll only pull high quality branches that make sense to be in the core of Play.

Pages