목록프로그래밍 (408)
쌓고 쌓다
필요성 먼저 코드를 보자. @Controller @RequestMapping("/form/items") @RequiredArgsConstructor @Slf4j public class FormItemController { private final ItemRepository itemRepository; @GetMapping public String items(Model model) { Map regions = new LinkedHashMap(); regions.put("SEOUL", "서울"); regions.put("BUSAN", "부산"); regions.put("JEJU", "제주"); model.addAttribute("regions", regions); return "form/items"; } @..
Item에 true, false 값을 관리하는 필드가 있다. @Data public class Item { private Boolean open; //오픈 여부 } 아래처럼 순수 HTML로 체크박스를 만들고 POST 요청을 보내면 문제가 있다. 체크박스를 선택한 경우에는 HTML Form에서 open=on이 넘어온다. 이 값은 스프링에서 true로 타입 변환이 이뤄지진다. 선택하지 않은 경우에는 서버에 null 값이 넘어온다. 자세히는 name="open" 값이 전혀 존재하지 않은 상태이다. 체크 박스 미선택 문제를 스프링MVC와 히든 필드로 해결할 수 있다. (미선택시 false, 선택시 true가 넘어오게) 어떻게 name="open"과 name="_open"으로 해결한다는걸까? 체크박스 선택시 op..
등록 폼 먼저 등록 폼의 html을 응답할때 모델에 빈 객체를 담아서 넘겨주자. th:object 사용을 위해 빈 오브젝트를 넘겨줄 필요가 있다. @GetMapping("/add") public String addForm(Model model) { model.addAttribute("item", new Item()); return "form/addForm"; } 넘어온 객체는 아래와 같이 타임리프를 사용하여 편리하게 사용할 수 있다. th:object="${item}"으로 넘어온 객체를 받는다. th:field는 HTML 태그인 id, name, value 속성을 자동으로 생성해준다. *{...}는 선택 변수 식이라고 th:object에서 선택한 객체에 대해 필드 접근한다. 위의 input 태그는 렌더링..
에러 발생 java.lang.IllegalStateException: Cannot call sendError() after the response has been committed org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Infinite recursion (StackOverflowError)] java.lang.StackOverflowError 보면 jackson 라이브러리에서 무한하게 에러 메시지를 보내면서 StackOverflow에러가 발생했다. 에러 원인 Poster @Entity @Getter @Setter public class Poster { @OneToMany(mappedB..
일대다 단방향 매핑에서 다대일 양방향 매핑으로 변경하고 이것저것 리팩토링하는 과정에서... The dependencies of some of the beans in the application context form a cycle 에러가 발생했다. 예를 들어 설명하자면. A 클래스 빈을 만드는 과정에서 B 클래스 빈을 주입해야하는 상황이다. 그래서 B 클래스 빈을 만들고자해서 B 클래스 빈을 만드는데 또 이 빈은 만드는데 A 클래스 빈을 주입 받아야하는 상황인것이다. 그럼 뭘 먼저 만들어야하는지 알 수 없기에 무한 참조가 일어나는 것이다. 그냥 필요할때마다 의존성 주입으로 끌어다 써도 문제 없을줄 알았던 나... 의존성을 잘 설계하는게 중요했었다. 양방향 의존성이라니!! 그러면 다른 서비스를 통해 만들어..
부모 엔티티와 연관관계가 끊어진 자식 엔티티를 자동으로 삭제할 수 있다. 부모 엔티티의 컬렉션에서 자식 엔티티의 참조만 제거하면 된다. Parent @Entity @Getter @Setter public class Parent { ... @OneToMany(mappedBy = "parent", cascade = CascadeType.PERSIST, orphanRemoval = true) private List child = new ArrayList(); } 아래의 코드를 수행하자. Parent parent = em.find(Parent.class, 12L); parent.getChild().remove(0); 자식 엔티티 삭제 쿼리가 날라간다. 고아 객체 제거는 참조가 제거된 엔티티가 어떤곳에서도 참조하..
부모와 자식 엔티티를 제거하려면 자식 엔티티를 하나씩 제거하고 부모 엔티티를 제거해야한다. 영속성 전이는 저장뿐만아니라 삭제도 가능하다. 부모 엔티티만 제거하면 자식 엔티티도 함께 제거하게 할 수 있는 것이다. Parent @Entity @Getter @Setter public class Parent { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @OneToMany(mappedBy = "parent", cascade = {CascadeType.PERSIST, CascadeType.REMOVE}) private List child = new ArrayList(); } cascade = {CascadeType.PERSIS..
영속성 전이를 사용하면 부모 엔티티를 저장할 때 자식 엔티티도 함께 저장할 수 있다. 영속성 전이를 사용하지 않았을때의 로직을 먼저 보자. 영속성 전이 사용 Parent @Entity @Getter @Setter public class Parent { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @OneToMany(mappedBy = "parent", cascade = CascadeType.PERSIST) private List child = new ArrayList(); } cascade 속성에 CascadeType.PERSIST 값을 주면 된다. Child @Entity @Getter @Setter public cl..