2017-02-16 1 views
0

나는 클라이언트를 관리하기위한 응용 프로그램을 개발 중이다. 필요한 테이블, 스키마, 컨트롤러 등을 모두 작성했습니다.Spring MVC + Thymeleaf - 관계 저장 @ManyToOne

클라이언트 엔티티가있는 클라이언트 엔티티에는 클라이언트 관계가 있습니다 (쌍방향, 비표준).

내가 가진 문제는 기존 클라이언트에 새로운 컴퓨터를 추가하는 것과 관련이 있습니다 (이 컴퓨터는 이미 존재합니다).

그래서 여기에 일부 코드 짧은 싹둑 있습니다 :

@Controller 
public class MachineController { 

... 
    @GetMapping("/machines/add/{clientId}") 
    public String addMachine(@PathVariable("clientId") int clientId, Model model) throws ClientNotFoundException { 
     model.addAttribute("machineTypes", MachineType.values()); 
     model.addAttribute("machine", new Machine()); 
     model.addAttribute("client", clientService.find(clientId)); 
     return "machines/form"; 
    } 
} 

    @PostMapping("/machines/save") 
    public String saveMachine(@ModelAttribute @Valid Machine machine, BindingResult bindingResult, Model model) 
      throws ClientNotFoundException { 

     model.addAttribute("machineTypes", MachineType.values()); 

     int clientId = machine.getClient().getId(); 
     LOG.debug("ClientId:{}", clientId); 
     // Client object is not filled here ! clientId is 0 (new client). 
} 

문제는 저장 기능을 가진 - 내가 HTTP POST에 의해 전송되는 기계 객체에 대한 클라이언트 개체를 대한 기존 전달하는 방법을 모르겠어요. 내 컨트롤러는 클라이언트가 전송되지 않는다는 불평과 BindingResult 오류 던지고있다 :

Field error in object 'machine' on field 'client.address.city: rejected value [null]; Field error in object 'machine' on field 'client.address.zipCode: rejected value [null]; Field error in object 'machine' on field 'client.name': rejected value [null];

내가 어떤 도움을 기대 loooking하고 있습니다.

HTML 양식은 아래에 제시 :

       <form class="form-horizontal" th:action="@{/machines/save}" th:object="${machine}" method="post" id="machineForm"> 
           <input type="hidden" th:field="*{id}"/> 

            <!-- Panel for machine --> 
           <div th:class="${#fields.hasErrors('machineType')}? 'form-group has-error has-feedback' : 'form-group'"> 
            <label class="control-label col-sm-4" for="manufacturer">Rodzaj:*</label> 
            <div class="col-sm-8"> 

             <select th:field="${machine.machineType}" class="form-control" id="machineTypeSelect"> 
              <option value="" disabled="disabled" selected="selected">Wybierz rodzaj</option> 
              <option th:each="type: ${machineTypes}" th:value="${type.name()}" th:text="${type}" th:attr="data-has-car=${type.hasCar()}"></option> 
             </select> 

             <div class="help-block" th:if="${#fields.hasErrors('machineType')}" 
              th:errors="*{machineType}"></div> 
            </div> 
           </div> 

           <div th:class="${#fields.hasErrors('manufacturer')}? 'form-group has-error has-feedback' : 'form-group'"> 
            <label class="control-label col-sm-4" for="manufacturer">Producent:*</label> 
            <div class="col-sm-8"> 
             <input type="text" 
               class="form-control" 
               id="manufacturer" 
               placeholder="Podaj producenta" 
               th:field="*{manufacturer}" /> 
             <div class="help-block" th:if="${#fields.hasErrors('manufacturer')}" 
              th:errors="*{manufacturer}"></div> 
            </div> 
           </div> 

           <div th:class="${#fields.hasErrors('model')}? 'form-group has-error has-feedback' : 'form-group'"> 
            <label class="control-label col-sm-4" for="model">Model:</label> 
            <div class="col-sm-8"> 
             <input type="text" 
               class="form-control" 
               id="model" 
               placeholder="Podaj model" 
               th:field="*{model}"/> 
             <div class="help-block" th:if="${#fields.hasErrors('model')}" 
              th:errors="*{model}"></div> 
            </div> 
           </div> 

           <div th:class="${#fields.hasErrors('productionYear')}? 'form-group has-error has-feedback' : 'form-group'"> 
            <label class="control-label col-sm-4" for="productionYear">Rok produkcji:*</label> 
            <div class="col-sm-8"> 
             <input type="number" 
               class="form-control" 
               id="productionYear" 
               placeholder="Podaj rok produkcji" 
               th:field="*{productionYear}"/> 
             <div class="help-block" th:if="${#fields.hasErrors('productionYear')}" 
              th:errors="*{productionYear}"></div> 
            </div> 
           </div> 

           <div th:class="${#fields.hasErrors('factoryNo')}? 'form-group has-error has-feedback' : 'form-group'"> 
            <label class="control-label col-sm-4" for="factoryNo">Numer fabryczny:</label> 
            <div class="col-sm-8"> 
              <input type="number" 
                class="form-control" 
                id="factoryNo" 
                placeholder="Podaj numer fabryczny" 
                th:field="*{factoryNo}"/> 
             <div class="help-block" th:if="${#fields.hasErrors('factoryNo')}" 
              th:errors="*{factoryNo}"></div> 
            </div> 
           </div> 

           <div th:class="${#fields.hasErrors('maxLoad')}? 'form-group has-error has-feedback' : 'form-group'"> 
            <label class="control-label col-sm-4" for="maxLoad">Max udżwig:</label> 
            <div class="col-sm-8"> 
             <div class="input-group"> 
             <input type="number" 
               class="form-control" 
               id="maxLoad" 
               placeholder="Max. udźwig" 
               aria-describedby="measure" 
               th:field="*{maxLoad}"/> 
              <span class="input-group-addon" id="measure">kg</span> 
             </div> 
             <div class="help-block" th:if="${#fields.hasErrors('maxLoad')}" 
              th:errors="*{maxLoad}"></div> 
            </div> 
           </div> 

           <div th:object="${machine.client}"> 
            <div th:class="${#fields.hasErrors('id')}? 'form-group has-error has-feedback' : 'form-group'"> 
             <label class="control-label col-sm-4" for="clientId">Wybrany klient:</label> 
             <div class="col-sm-8"> 
              <span class="form-control-static" id="selectedClient">Nie wybrano! Wyszukaj po prawej</span> 
              <input type="hidden" th:field="${machine.client.id}" id="clientId" /> 
              <div class="help-block" th:if="${#fields.hasErrors('id')}" 
               th:errors="${machine.client.id}"></div> 
             </div> 
            </div> 
           </div> 

           <div id="machineCar" th:object="${machine.car}"> 

            <div th:class="${#fields.hasErrors('make')}? 'form-group has-error has-feedback' : 'form-group'"> 
             <label class="control-label col-sm-4" for="carMake">Marka pojazdu:*</label> 
             <div class="col-sm-8"> 
              <input type="text" 
                class="form-control" 
                id="carMake" 
                placeholder="Podaj markę pojazdu" 
                th:field="*{make}"/> 
              <div class="help-block" th:if="${#fields.hasErrors('make')}" 
               th:errors="*{make}"></div> 
             </div> 
            </div> 

            <div th:class="${#fields.hasErrors('vin')}? 'form-group has-error has-feedback' : 'form-group'"> 
             <label class="control-label col-sm-4" for="factoryNo">VIN:</label> 
             <div class="col-sm-8"> 
              <input type="number" 
                class="form-control" 
                id="vin" 
                placeholder="Podaj numer VIN" 
                th:field="*{vin}"/> 
              <div class="help-block" th:if="${#fields.hasErrors('vin')}" 
               th:errors="*{vin}"></div> 
             </div> 
            </div> 
           </div> 
            <div class="form-group"> 
             <div class="col-xs-12"> 
              <button type="submit" class="btn btn-primary">Zapisz dane</button> 
             </div> 
            </div> 
           </form> 

답변

0

내 문제가 해결되었습니다. 확실한 해결책인지는 모르겠지만 작동합니다.

그래서, 단순히 기계의 실체에 :

public class Machine { 

    @Id 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "MACHINE_SEQUENCE") 
    private int id; 

    // ... 
    @ManyToOne(optional = false, fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE}) 
    @JoinColumn(name = "client_id", nullable = false) 
    @Valid // REMOVED 
    private Client client; 

더 이상 클라이언트 필드 위에 따라서 스프링 MVC가 검증되지 않은 Thymeleaf 양식에 @Valid 주석을 제거했습니다.

또 다른 해결책은 클라이언트 세부 숨겨진 입력 (이름, 회사 및 하위 주소 객체)를 포함 할 수 있도록 thymeleaf이 완료 객체를 전송할 수 있으며, BindingResult 불평하지 않습니다 ...

0

시도는 HTML의 형태로

<input type="hidden" name="client.id" value="${client.id}" /> 

을 추가, ID로 그 클라이언트 객체는 값을 생성 한 다음에 나머지를 떠날 것 저장소, 그것은 id를 레코드를 연관시키기 만하면된다.

+0

내가했던 이전에 숨겨진 입력하지만 여전히 작동하지 않습니다. – mlewandowski

+0

HTML 양식을 공유 하시겠습니까? –

+0

위의 질문에서 html 양식을 게시했습니다. – mlewandowski