Results 1 to 5 of 5

Thread: Using @Valid removes child collections

Hybrid View

  1. #1
    Join Date
    Jul 2010
    Posts
    16

    Default Using @Valid removes child collections

    I have two different pages where different parts of an object can be added/updated. One main screen where simple information like name etc are specified and another form where a child collection is updated. If I have 2 elements added to the child collection and then go back into the general form and resave the data, it wipes out the child collections here is the code

    Code:
    /*** StoreContoller.java ***/
    @RequestMapping(value = "/store", method = RequestMethod.GET)
    	public String store(@RequestParam(defaultValue="") String storeId, Model model){
    		//updating existing store
    		if(!storeId.equals("")){
    			model.addAttribute("store", storeDao.getStoreById(storeId));
    		}
    		//adding new store
    		else{
    			model.addAttribute("store", new Store());
    		}
    		return "store";
    	}
    
    @RequestMapping(value = "/store", method = RequestMethod.POST)
    	public String storeSubmit(@Valid Store store, BindingResult result){
    		if(!result.hasErrors()){
    			//now save the store
    			log.debug("adding/updating store " + store);
    			storeDao.saveStore(store);
    			return "redirect:/";
    		}
    		log.error("error in binding store", result.toString());
    		return "store";
    	}
    Code:
    /*** StoreDoa */
    public void saveStore(Store store){
    		log.debug("saving store " + store);
    		Session session = sessionFactory.getCurrentSession();
    		session.saveOrUpdate(store);
    		session.flush();
    	}
    Code:
    /**** Store.java */
    @Entity
    @Table(name="clicksvn_stores")
    public class Store implements Serializable {
    @Id
    	private String id = IDGenerator.createId();
    	
    	@NotEmpty
    	private String name;
    	@NotEmpty
    	private String server;
    	
    	@NotEmpty
    	private String username;
    	@NotEmpty
    	private String password;
    	
    	private String schedulingExpression;
    	
    	private boolean scheduled;
    	
    	@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, orphanRemoval=true)
    	@JoinColumn(name="store_id")
    	private Collection<Project> projects = new LinkedHashSet<Project>();
    	
     .....
    }
    Code:
    /**** Project class */
    @Entity
    @Table(name="clicksvn_store_projects")
    public class Project implements Serializable {
    	private static final long serialVersionUID = -276787615885478824L;
    
    	@Id
    	private String id = IDGenerator.createId();
    	
    	private String internalName;
    	private String displayName;
    	
    	@ManyToOne
    	@JoinColumn(name="store_id", insertable=false, updatable=false)
    	private Store store;
    ...
    }
    Any help would be appreciated. I have tried specifying dynamic update as true on Store entity but still doesnt helps.

  2. #2
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,632

    Default

    The problem is you aren't using the model object but a new fresh instance onto which the submitted request parameters are bound.

    Either store the object in the session in between requests (using @SessionAttributes) or create a @ModelAttribute method which retrieves the object from the database on subsequent requests.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  3. #3
    Join Date
    Jul 2010
    Posts
    16

    Default

    Quote Originally Posted by Marten Deinum View Post
    The problem is you aren't using the model object but a new fresh instance onto which the submitted request parameters are bound.

    Either store the object in the session in between requests (using @SessionAttributes) or create a @ModelAttribute method which retrieves the object from the database on subsequent requests.
    That makes sense. How do i use the model attribute. I tried changing the controller method to

    Code:
    @RequestMapping(value = "/store", method = RequestMethod.POST)
    public String storeSubmit(@Valid @ModelAttribute("store") Store store, BindingResult result){
    but that didnt seemed to help

  4. #4
    Join Date
    Jul 2010
    Posts
    16

    Default

    okay I am still a little confused about what is the best way to do this but these are the changes I made and its working fine now. Thanks
    Code:
    //StoreController
    	@ModelAttribute("store")
    	public Model getStore(String storeId, Model model){
    	  if(storeId != null){
    	    Store store = storeDao.getStoreById(storeId);
    	    if(store != null){
    	      model.addAttribute("store", store);
    	    }	    
    	    else{
    	      model.addAttribute("store", new Store());
    	    }	    
    	  }	  
    	  return model;
    	}
    
    @RequestMapping(value = "/store", method = RequestMethod.POST)
    public String storeSubmit(@Valid @ModelAttribute("store") Store store, BindingResult result){
    ...

  5. #5
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,632

    Default

    If you have a @ModelAttribute annotated method you don't need to add it to the model, simply return the Store object and it will be added to the model for you. That saves you a couple of lines.

    Code:
    @ModelAttribute("store")
    public Store getStore(String storeId){
      Store store = new Store();
      if (storeId != null) {
        store = storeDao.getStoreById(storeId)
      }
      return store;
    }
    Basically it depends on what you want. THe @ModelAttribute is executed before each request handling method on the controller, advantage is that your application is stateless (nothing is stored in the session). Drawback is the object is retrieved for each request. Storing it in the session overcomes this last drawback but makes your application stateful and storing large amounts of data in the session can become problematic.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •