Search code examples
javaspringjspspring-mvcspring-form

Spring Form binding object one to many


I have a problem. I use Spring Mongo Data, Web, mvc ecc... I want to bind a complex object with his dependency, but my solution not work.

This is the code:

MODELS

public class Foo {

   @Id
   private String id;

   private String nome;

   private String descrizione;

   private Date dataCreazione;

   private Date dataUltimaModifica;

   @DBRef
   private Dependency dependency;   //getters and setters
}


public class Dependency {
   @Id
   private String id;

   @Indexed(unique = true)
   private String nome;

   private String descrizione;

   private Date dataCreazione;

   private Date dataUltimaModifica;

  //GETTERS AND SETTERS

}

CONTROLLER

@RequestMapping(value = Constants.ADD, method = RequestMethod.GET)
public String add(Model model) {

    Foo foo = new Foo();
    model.addAttribute("fooForm", foo);
    model.addAttribute("depList",depService.getList());

    return "foo/add";
}

@RequestMapping(value = Constants.ADD, method = RequestMethod.POST)
public String addPost(@ModelAttribute("fooForm") Foo foo, BindingResult result, Model model) {
   //Check if foo is not null
}

VIEW

<form:form class="form-horizontal" method="post" modelAttribute="fooForm" action="${addFoo}">
    <spring:bind path="dependency">
       <div class="form-group">
         <label for="dependency" class="col-sm-2 control-label">Dependency</label>
         <div class="col-sm-10">
         <form:errors path="dependency" class="control-label" />
           <form:select path="dependency" title="Dependency" >
             <form:option value="">&nbsp;</form:option>
               <form:options items="${depList}" />
           </form:select>
           <p class="help-block mb-0">Select a dependency</p>
         </div>
      </div>
   </spring:bind>
   <spring:bind path="nome">
     <div class="form-group">
       <label for="nome" class="col-sm-2 control-label">Nome</label>
       <div class="col-sm-10">
       <form:errors path="nome" class="control-label" />
          <form:input path="nome" type="text" class="form-control" id="nome" placeholder="Nome Foo" />
       <p class="help-block mb-0">Specificare il nome of Foo</p>
       </div>
    </div>
 </spring:bind>
 <spring:bind path="descrizione">
    <div class="form-group">
       <label for="descrizione" class="col-sm-2 control-label">Descrizione</label>
        <div class="col-sm-10">
           <form:errors path="descrizione" class="control-label" />
              <form:input path="descrizione" type="text" class="form-control" id="descrizione" placeholder="Descrizione" />
      <p class="help-block mb-0">Inserire una breve descrizione per Foo</p>
        </div>
     </div>
  </spring:bind>
  <div class="form-group">
      <div class="col-sm-offset-2 col-sm-10">
          <button type="submit" class="btn btn-rounded btn-primary btn-sm">Salva</button>
      </div>
  </div>
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />

When i post the form, I get a correct value for nome and descrizione but dependency is always null... why?

Example:

 //METHOD POST
 public String addPost(@ModelAttribute("fooForm") Foo foo, 
        BindingResult result, Model model) {

      foo.getNome is not null
      foo.getDescrizione is not null
      foo.getDependency is always null ... why?
 }

Thanks in advance.


Solution

  • I have found the solution! It's very simple!

    We need a Converter Object because the binded form return Dependency ID and not the entire Object!

    Well, this is the solution:

    Converter

    
        
        public class DependencyConverter implements Converter {
            @Autowired
            private CategoriaRepository repository;
    
            @Override
            public Categoria convert(String id) {
                return repository.findById(id);
            }
        }
        
    
    

    Now we register the converter in our application-context.xml

    <mvc:annotation-driven conversion-service="conversionService"/>
    
    <bean id="conversionService"
        class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="myPackage.DependencyConverter" />
            </set>
        </property>
    </bean>
    

    that's all...

    I hope this will be helpful in the future....

    Bye Bye...