简体   繁体   中英

SpringMVC/JSTL/JPA Integration: update existing child element and add new child element to a parent entity using Spring MVC

I'm new to SpringMVC and JPA. I'm doing a student project using these frameworks. In the project, I want to implement a JSP to update existing child element and add new child element to a parent entity. My solution worked. But I think there should be a more elegant or "standard" way to do it. Following is what my code looks like:

JPA Entity

@Entity
public class Parent {
    @Id
    @GeneratedValue
    private Integer id;
    private String name;
    @OneToMany(mappedBy = "parent", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
    private Set<Child> children = new HashSet<Child>();
    // constructors, getters and setters
}

@Entity
public class Child{
    @Id
    @GeneratedValue
    private Integer id;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "parentId")
    private Parent parent;

    private String name;
    // constructor getter and setter
}

Command Name class

public class CommandName {
    private Parent parent;
    private List<Child> existingChildren = new ArrayList<Child>();
    private List<Child> newChildren = new ArrayList<Child>();

    private static final int MAX_NUM_NEW_CHILDREN = 3;

    public CommandName(Parent parent) {
          this.parent = parent;
          this.existingChildren.addAll(parent.getChildren());
          for (int i = 0; i < MAX_NUM_NEW_CHILDREN; ++i) {
                newChildren.add(new Child());
          }
    } 
    // getters and setters
}

Controller class

@Controller
public class MyController {
    @Autowired
    private ParentRepository parentRepository;

    @RequestMapping(value = "/editParent/{parentID}", method = RequestMethod.GET)
    public String editParent(ModelMap model, @PathVariable("parentID") Integer parentID) {
        CommandName cn = new CommandName(parentRepository.findOne(parentID));
        model.addAttribute("cn", cn);
        return "edit";
    }

    @RequestMapping(value = "/saveParent", method = RequestMethod.POST)
    public String saveParent(CommandName cn, BindingResult bindingResult) {
        Parent parent = cn.Parent();
        List existChildren = cn.getExistingChildren();
        for (Child c : existChildren) {
            c.setParent(parent);
        }
        List newChildren = cn.getNewChildren();
        for (Child c: newChildren) {
            c.setParent(parent);
        }
        parent.getChildren().addAll(existChildren);
        parent.getChildren().addAll(newChildren);
        parentRepository.save(parent);
        return "redirect:/view";
    }
}

form in the edit.jsp

<f:form role="form" action="/saveParent" commandName="cn">

<f:hidden path="parent.id"/>
<f:label path="parent.name">Parent Name</f:label>

<f:input type="text" path="parent.name"/>

<label>Children</label>
<c:forEach items="${cn.existingChildren}" var="child" varStatus="status">
    <f:hidden path="child.id"/>
    <f:input type="text" path="existingChildren[${status.index}].name"/>
</c:forEach>

<c:forEach items="${cn.newChildren}" var="child" varStatus="status">
    <f:input type="text" path="newChildren[${status.index}].name"/>
</c:forEach>

<button type="submit">Submit</button>
</f:form>

These set of code worked: the parent and the existing children are updated. The new children are created. But in the saveParent() method, I have to do the following to relink everything. Is there any better way to approach this (a better commandName class, a better jsp form?) Thanks a lot!

List existChildren = cn.getExistingChildren();
for (Child c : existChildren) {
    c.setParent(parent);
}

As in your question you dont have update parent, and no need to plasy with existing childrens.. Only add new childrens.. so, Change /saveParent POST from:

@RequestMapping(value = "/saveParent", method = RequestMethod.POST)
    public String saveParent(CommandName cn, BindingResult bindingResult) {
        Parent parent = cn.Parent();
        List existChildren = cn.getExistingChildren();
        for (Child c : existChildren) {
            c.setParent(parent);
        }
        List newChildren = cn.getNewChildren();
        for (Child c: newChildren) {
            c.setParent(parent);
        }
        parent.getChildren().addAll(existChildren);
        parent.getChildren().addAll(newChildren);
        parentRepository.save(parent);
        return "redirect:/view";
    }

To:

@RequestMapping(value = "/saveParent", method = RequestMethod.POST)
    public String saveParent(CommandName cn, BindingResult bindingResult) {
        Parent parent = cn.getParent();
        if(parent.getId()!=null)//if parent id is not null, then retrieve the parent from database. and update it.
            parent = parentRepository.findOne(cn.getParent().getId());
        for(Child c : cn.getNewChildren()){
            c.setParent(parent);
            parent.getChildren().add(c);
        }
        parentRepository.save(parent);
        return "redirect:/view";
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM