2014-05-14 2 views
1

저는 SpringMVC와 SpringJPA를 사용하고 있습니다. 그리고 나는 심지어 웹 서비스를 개발하지 않고 REST 스타일을 선호한다. 내가 좋아하는 엔티티/모델 프로젝트가 백엔드에 내가 Thymeleaf을 사용하고있는 프론트 엔드에서 Spring MVC와 JPA를 사용하여 모델을 업데이트하는 올바른 방법은 무엇입니까?

, 상기 AbstractPersistable에서

@Entity 
    @Table(name = "projects") 
    public class Project extends AbstractPersistable<Long> { 

     private static final long serialVersionUID = 7075433538058077502L; 

     @Size(min = 2, max = 30) 
     @NotBlank 
     private String name; 

     @NotNull 
     @Enumerated(EnumType.STRING) 
     private ProjectCategory category; 

     @Temporal(TemporalType.DATE) 
     @NotNull 
     @DateTimeFormat(iso = ISO.DATE) 
     private Date startDate; 

     @Temporal(TemporalType.DATE) 
     @NotNull 
     @DateTimeFormat(iso = ISO.DATE) 
     private Date endDate; 

는 setId 방법은 보호되고, 그래서 이드 디렉토리를 설정할 수 없습니다 이 엔티티. (. 보호로는 SpringJPA이 setId 방법을 정의하는 몇 가지 이유가 있어야합니다, 나는 내가 setId 방법을 덮어 쓸 수 있습니다 알고 있지만, 나는이 ID에 작업을 수행하는 올바른 방법은 아니라고 생각)

내 컨트롤러와 같은 것입니다 :

@RequestMapping(value = "/{id}/edit", method = RequestMethod.GET) 
    public String edit(@PathVariable("id") Long id, Model model) { 
     model.addAttribute("project", projectService.find(id)); 
     return "projects/edit"; 
    } 

    @RequestMapping(value = "/{id}", method = RequestMethod.PUT) 
    public ModelAndView update(@PathVariable("id") Long id, @Valid Project project, BindingResult result, RedirectAttributes redirect) {   

     if (result.hasErrors()) { 
      return new ModelAndView("projects/edit"); 
     } 

     try { 
      projectService.update(project); 
      logger.info(project.getName() + " project has been updated."); 
      redirect.addFlashAttribute(GLOBAL_MESSAGE, "Project updated successfully."); 
     } catch (BusinessException e) { 
      ModelAndView view = new ModelAndView("projects/edit"); 
      view.addObject(BUSINESS_ERROR, e.getMessage()); 
      return view; 
     } 

     return new ModelAndView(redirectTo("/projects")); 
    } 

지금 내 컨트롤러에서 Project 객체의 ID는 SpringMVC로 설정할 수 없습니다. 한 가지 문제는 BindingResult에 오류가있는 경우 사용자가 올바른 프로젝트 정보를 입력 할 수 있도록 id 값이없는 Project 객체로 '프로젝트/편집'뷰에 요청을 전달해야한다는 것입니다.

<form id="project-form" th:action="@{'/projects/' + ${project.id}}" th:object="${project}" th:method="put" class="form-horizontal"> 
</form> 

그런 다음 form 태그의 action 속성이 프로젝트의 id 값이 없습니다 :

내보기 양식은 같다. 조치가/projects/null이기 때문에 사용자가 오류를 수정 한 후 양식을 다시 제출할 수 없습니다.

SpringMVC, SpringJPA 및 REST 스타일을 올바르게 사용하는 방법은 무엇입니까? 나를 위해, SpringMVC API에 대한 오해가 있습니까?

SpringMVC 및 SpringJPA에 대해 전체 CRUD가있는 예제 및 오픈 소스 프로젝트가 있습니까?

+0

이 추상 클래스의 목적은 무엇입니까? 내가 생각할 수있는 대부분의 시나리오에서는 과도한 것처럼 보인다. – chrylis

+0

이 추상은 Spring JPA에서 온 것입니다. 엔티티는 EntityManager에 의해 관리되어야하므로 ID를 직접 수정하면 안된다고 생각합니다. – Chris

답변

0

나는이 문제에 직면 해왔다. 컨트롤러 클래스 (당신이 언급 한대로) setId 덮어 쓰기

  1. POST/PUT 메소드 내
  2. 호출 setId (당신은 당신의 경로에 ID가) : 두 가지 방법이 있습니다 보인다. 내 setId을 덮어 쓴

)

편집 : 나는 좋은 솔루션을 가지고

확인 다른 형태의 싸움 후. 나는 바인더를 사용했습니다. 컨트롤러 클래스에서 나는 그것을 초기화했습니다

@InitBinder 
    protected void initBinder(WebDataBinder binder) { 
     binder.registerCustomEditor(Player.class, new PropertyEditorSupport() { 
      @Override 
      public void setAsText(String text) { 
       Player custom = repositoryPlayerService.findById(Integer.parseInt(text)); 
       setValue(custom); 
      } 
     }); 
    } 

을 내 JSP에서 FORM 태그 안에 : 당신이 엔티티 (OD 데이터가 사용중인 객체)를 얻을 것이다 이런 식으로

 <form:form id="updatePlayerForm" action='' modelAttribute="player" method="post"> 
     .... 
    <input id="player" type="hidden" name="player" value="${player.id}" /> 
    .... 
    </form:form> 

와 ID는 컨트롤러의 POST 메서드에서 채워집니다.

+0

SessionAttribute 및 ModelAttribute를 사용하여 ID를 내 모델에 바인딩합니다. 양식이 제출 된 후 SessionStatus.setComplete()가 호출됩니다. 이것이 나의 해결책이다. – Chris

+0

흠 ...이 경우 ID에 대한 정보가 두 배가됩니다[email protected] ("id")에 ID가있는 동안 ID가있는 다른 세션 속성이 필요하지 않습니다. – user007