Announcement Announcement Module
Collapse
No announcement yet.
Managing a one-to-many relationship within a form when creating a new master entity Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Managing a one-to-many relationship within a form when creating a new master entity

    Hello guys!

    I've already searched a lot on the web to find a solution to my problem, but I managed none of them. I think it's quite specific and a curiously undocumented point.

    I'm developing using a Spring Fuse generated project (i.e. with Spring 3, Spring MVC 3 and Hibernate 3.6). I'll try to simplify my problem to make it more comfortable to read.

    So, let's say I've 3 JPA entities:

    Code:
    @Entity
    @Table(name = "consult")
    public class Consult
        private Integer id;
        private String name;
        private Set<ConsultTechno> consultTechnos; // one-to-many
        /* getters & setters */
    }
    Code:
    @Entity
    @Table(name = "consult_techno")
    public class ConsultTechno {
        private Integer id;
        private Techno techno; // many-to-one
        private Consult consult; // many-to-one
        private String level; // 1 <= level <= 4
        /* getters & setters */
    }
    Code:
    @Entity
    @Table(name = "techno")
    public class Techno {
        private Integer id;
        private String name;
        private Set<ConsultTechno> consultTechnos; // one-to-many
        /* getters & setters */
    }
    As you can see, a Consult contains n ConsultTechnos, which are caracterized by a level and a Techno (id + name). All the available technos are already persisted in the database. So, the entity ConsultTechno plays the part of relation-entity between a Consult and a Techno, with just an additionnal attribute level of String.

    What I would like to do, is when creating a new Consult (the C of CRUD), allowing the user to dynamically add ConsultTechnos by specifying the Techno and the level required.

    What I already tried

    In my JSP file which generates the HTML form used to create a new Consult:

    Code:
    ...
    <script type="text/javascript">
    $(function() {
    	var index = 0;
    	$("#add-techno").click(function() {
    		$(this).before(function() {
    			var html = "";
    			html += "<input type=\"text\" name=\"consultTechnos[" + index + "].techno.id\" />";
    			html += "<input type=\"text\" name=\"consultTechnos[" + index + "].level\" />";
    			html += "<br />";
    			return html;
    		});
    		index++;
    	});
    });
    </script>
    <button id="add-techno" type="button">Add a techno</button>
    ...
    As you probably imagine, at the end, the two text inputs will be two selects: one listing technos (id => name) and the other listing levels ("1" => "easy", ..., "4" => "hard"). I've first put two text inputs to simplify the development. That layout part works well, but when I try to upload the form, an exception is catched:

    Code:
    Invalid property 'consultTechnos[0]' of bean class [com.Consult]: Cannot get element with index 0 from Set of size 0, accessed using property path 'consultTechnos[0]'
    I think I do understand why this exception is thrown: the initial model attribute consult of Consult has an empty Set of consultTechnos.

    So, I thought of putting the model attribute consult of Consult in a session, and using AJAX, modifying it when the user clicks on the button (e.g. consult.getConsultTechnos().add(new ConsultTechno())), but I would like to have your opinion on it before developing it.

    I found some tracks on the web which seem to implement an initBinder() method in the Controller, for example:

    Code:
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        // I should probably add something here...
    }
    But in fact, I don't really know how to implement that method, and if that's the good way to resolve my problem...

    I've just one constraint: the ConsultTechnos shouldn't be perstisted before the user submits the form creating a new Consult, because if the user finally closes his browser without submitting the form (for example), ConsultTechnos could be uselessly persisted.

    I also read some articles about the <spring:bind /> tag, but I'm not sure if it's applicable for this context. What I understood is that this tag could be interesting when updating a Consult (the U of CRUD), but you won't be able to add a new Techno though...

    Well, I'm a bit lost! Any idea or proposition?

    Thanks a lot!

    Chris
    Last edited by sp00m; Mar 13th, 2012, 10:37 AM.

  • #2
    A solution

    Here is the solution I implemented.

    Comment

    Working...
    X