Announcement Announcement Module
Collapse
No announcement yet.
How to populate back reference while binding nested autogrown list? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • How to populate back reference while binding nested autogrown list?

    Preface

    I've got a classical Parent-Child problem. Here's the code:

    Code:
    @Entity
    public class Supply {
        @OneToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH, CascadeType.DETACH }, mappedBy = "supply")
        private List<SupplyItem> items = new ArrayList<SupplyItem>();
        
        // Getters/Setters and id field
    }
    
    @Entity
    public class SupplyItem {
        @NotNull
        @ManyToOne
        private Supply supply;
    
        private Integer quantity;
    
        // Getters/Setters and id field
    }
    When I'm trying to save a bean tree in one go:
    Code:
    Supply supply = new Supply();
    SupplyItem item = new SupplyItem();
    
    supply.getItems().add(item);
    
    entityManager.persist(supply);
    Naturally I get ConstraintViolationException since I have validation configured and item.supply is null.

    Hibernate in Action suggests the following approach:

    Code:
    public class Supply {
        // Skipped
        public void addItem(SupplyItem item) {
            item.setSupply(this);
            items.add(item);
        }
        // Skipped
    }
    
    Supply supply = new Supply();
    SupplyItem item = new SupplyItem();
    
    supply.addItem(item);
    
    entityManager.persist(supply);
    Problem

    The problem is that I don't populate items by hand, thus I cannot use a helper addItem() method. Instead I get my supply object constructed via web binding. The items list is populated by means of list autogrowing facility.

    So my view markup looks like this:
    HTML Code:
    <form:form modelAttribute="supply">
        <!-- Other supply fields -->
        <form:input path="items[0].quantity" />
        <form:input path="items[1].quantity" />
    </form:form>
    I know that I could iterate over all the supply items and set the back reference to supply, but that looks like a hack to me.

    So I wonder is there any other way to make binder/expression parser/whatever to do that for me ? Maybe I could provide the factory method for supply items creation somehow?

    If that matters I use WebFlow, but I would like to know whether it is possible for MVC too.

  • #2
    Ok, some digging shown that auto growing is implemented in spring-expression (see Indexer.java:285 and Indexer.java:288) which is used by both MVC and WebFlow. So the behavior is consistent, and that's a good thing to know.

    What's bad is that new instances are created via Class.newInstance() rather then using a factory, and thus the instantiation process cannot be controlled .

    Are there any other options I could cope with my problem?

    Comment

    Working...
    X