해결된 질문
작성
·
98
0
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.
1. 강의 내용과 관련된 질문을 남겨주세요.
2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.
(자주 하는 질문 링크: https://bit.ly/3fX6ygx)
3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.
(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)
질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.
=========================================
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예/아니오)
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)
[질문 내용]
안녕하세요 강의를 잘 듣고있는 학생입니다.
질문의 내용은, 회원가입 후 제출을 누른 뒤, 다시 원래대로 redirect:/까지는 return 되지만, H2 database에 저장이 되지 않는 문제가 있어서 질문드립니다.
제가 생각한 문제의 원인은 3가지입니다.
memberrepository.join의 문제인가? (애초부터 저장이 되지 않음.)
h2 database의 연결 문제인가?
스프링 코드의 문제인가?
이렇게 3가지의 문제로 생각해볼 수 있는데요,
다른분들의 오류도 찾아보고 나름대로 열심히 찾아보았지만,
모두 검토해본 결과, 이 3가지의 문제+다른분들과 겹치는 문제가 아니여서 질문드립니다.
제가 이 3가지의 문제에서 해결책을 찾을 수 없던 이유는 다음과 같습니다.
그렇다면(이것이 맞다면), MemberServiceTest의 저장도 가능하지가 않을 뿐더러, 이것의 데이터도 저장이 되지 않아야 한다.
허나 MemberServiceTest를 돌려본 결과, 테스트는 통과하고 .join도 다 가능하다 라는 것을 알 수 있었습니다.
코드 ::MemberServiceTest
@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
public class MemberServiceTest {
@Autowired MemberService memberService;
@Autowired MemberRepository memberRepository;
@Autowired EntityManager em;
@Test
//@Rollback(value = false) --> 눈으로 확인해 보고 싶을때
public void 회원가입() throws Exception {
//given
Member member = new Member();
member.setName("kim");
//when
Long saveId = memberService.join(member);
//then
em.flush();
assertEquals(member,memberRepository.findOne(saveId));
}
h2.database의 연결 문제인가?
이것에 대해 제가 아니라고 생각한 이유는 다음과 같습니다.
그 이후의 강의인 상품 등록을 했을때, 신기하게 상품 등록은 정상적으로 되었습니다.
h2 database에도 등록이 되었고 상품 목록도 나타났습니다.
이렇게 등록을 했을때.
이렇게 데이터베이스에도 있는것을 확인할 수 있었고,
상품 목록도 제대로 있는것을 확인할 수 있습니다.
따라서 2번도 맞지 않는다고 생각했습니다.
3.스프링 코드의 문제인가?
:: MemberController 코드
package jpabook.jpashop.controller;
import jakarta.validation.Valid;
import jpabook.jpashop.domain.Address;
import jpabook.jpashop.domain.Member;
import jpabook.jpashop.service.MemberService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import java.util.List;
@Controller
@RequiredArgsConstructor
public class MemberController {
private final MemberService memberService;
@GetMapping(value = "/members/new")
public String createForm(Model model) {
model.addAttribute("memberForm", new MemberForm());
return "members/createMemberForm";
}
@PostMapping(value = "/members/new")
public String create(@Valid MemberForm form, BindingResult result) {
if (result.hasErrors()) {
return "members/createMemberForm";
}
Address address = new Address(form.getCity(), form.getStreet(),
form.getZipcode());
Member member = new Member();
member.setName(form.getName());
member.setAddress(address);
memberService.join(member);
return "redirect:/";
}
@GetMapping(value = "/members")
public String list(Model model){
List<Member> members = memberService.findMembers();
model.addAttribute("members",members);
return "members/memberList";
}
}
::creatememberForm.html코드
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="fragments/header :: header" />
<style>
.fieldError {
border-color: #bd2130;
}
</style>
<body>
<div class="container">
<div th:replace="fragments/bodyHeader :: bodyHeader"/>
<form role="form" action="/members/new" th:object="${memberForm}"
method="post">
<div class="form-group">
<label th:for="name">이름</label>
<input type="text" th:field="*{name}" class="form-control"
placeholder="이름을 입력하세요"
th:class="${#fields.hasErrors('name')}? 'form-control
fieldError' : 'form-control'">
<p th:if="${#fields.hasErrors('name')}"
th:errors="*{name}">Incorrect date</p>
</div>
<div class="form-group">
<label th:for="city">도시</label>
<input type="text" th:field="*{city}" class="form-control"
placeholder="도시를 입력하세요">
</div>
<div class="form-group">
<label th:for="street">거리</label>
<input type="text" th:field="*{street}" class="form-control"
placeholder="거리를 입력하세요">
</div>
<div class="form-group">
<label th:for="zipcode">우편번호</label>
<input type="text" th:field="*{zipcode}" class="form-control"
placeholder="우편번호를 입력하세요">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
<br/>
<div th:replace="fragments/footer :: footer" />
</div> <!-- /container -->
</body>
</html>
여러번 비교해 본 결과 강의자료와 강의에 있는 코드와 다름이 없다는 것을 알게 되었습니다.
오류 내용이 나타나면 해결하기가 더 쉬운데, 오류내용이 나오지 않아서 해결하기 더 어려운 것 같습니다.
사실 이후에 강의도 듣고 있다가 이 문제가 해결이 되지 않아서 계속 막혀서 고생하고 있는 상황입니다...
도와주시면 감사하겠습니다..
코드 확인해보았습니다.
코드를 확인해봐야 알 수 있는 문제였네요 ^^
질문에서 남기신 것처럼 MemberService의 join()과 관련된 문제였습니다.
MemberService의 클래스 레벨로 @Transactional 선언이 readOnly로 걸려있었고
이로 인해 저장이 정상동작하지 않은 것이였습니다.
아래 TODO에 추가한 것처럼 조회동작이 아닐 때는 readOnly=false(default)로 적용해주세요^^