인프런 커뮤니티 질문&답변

borashin님의 프로필 이미지
borashin

작성한 질문수

[개념은 호옹~, 실습 빡] 스프링 부트, 입문!

15 데이터 수정하기(DB까지 바뀐 거 맞죠?)

15강 DTO ArticleForm 수정 후 새 데이터 입력 질문

작성

·

359

1

- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요!
- 먼저 유사한 질문이 있었는지 검색해보세요.
- 서로 예의를 지키며 존중하는 문화를 만들어가요.
- 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.

 

데이터 수정 시 수정한 데이터의 id를 받아오기 위해서 ArticleForm에 toEntity 메소드 return을

return new Article(null, title, content)에서 return new Article(id, title, content)로 수정하였는데요, 그렇게되면 새로운 데이터를 생성하는 ArticleController의 createArticle메소드에서 에러가 납니다. 처음 데이터 생성 시 id는 자동생성을 하게 해두고 new.mustache에서 id값을 input으로 받아오지 않았어서 그런것이라고 생각되는데, 혹시 해결 방법이 있을까요?

답변 2

0

borashin님의 프로필 이미지
borashin
질문자

ArticleController.java

package com.example.firstproject.controller;

import com.example.firstproject.dto.ArticleForm;
import com.example.firstproject.entity.Article;
import com.example.firstproject.repository.ArticleRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;

import java.util.List;
import java.util.Optional;

@Controller
@Slf4j //Logging을 위한 어노테이션
public class ArticleController {
    @Autowired // 스프링부트가 미리 생성해놓은 객체를 가져다가 자동 연결!
    private ArticleRepository articleRepository;

    @GetMapping("/articles/new")
    public String newArticleForm(){

        return "articles/new";
    }

    @PostMapping("/articles/create")
    public String createArticle(ArticleForm form){
        log.info(form.toString());
       // System.out.println(form.toString()); -> Logging 기능으로 대체

        // 1. Dto(form)를 변환해서 Entity로 바꿔야 함!
        Article article = form.toEntity();
        log.info(article.toString());

        // 2. Repository에게 Entity를 DB안에 저장하게 해야 함!
        Article saved = articleRepository.save(article);
        log.info(saved.toString());

      //  return "redirect:/articles/" + saved.getId();
        return "";
    }

    @GetMapping("/articles/{id}")
    public String show(@PathVariable Long id, Model model){
        log.info("id" + id);

        // 1. id로 데이터를 가져옴!
        Article articleEntity = articleRepository.findById(id).orElse(null);

        // 2. 가져온 데이터를 model에 등록!
        model.addAttribute("article", articleEntity);

        // 3. 보여줄 페이지를 설정!
        return "articles/show";
    }

    @GetMapping("/articles")
    public String index(Model model){

        // 1. 모든 article을 가져온다
            // casting error 해결방법 1 - List<Article> articleEntityList = (List<Article>)articleRepository.findAll();
            // casting error 해결방법 2 - Iterable<Article> articleEntityList = articleRepository.findAll();
        Iterable<Article> articleEntityList = articleRepository.findAll();

        // 2. 가져온 article 묶음을 뷰로 전달 - Model 사용해야죠
        model.addAttribute("articleList", articleEntityList);

        // 3. 뷰 페이지를 설정
        return "articles/index"; //articles/index.mustache
    }

    // go to editing page
    @GetMapping("/articles/{id}/edit")
    public String edit(@PathVariable Long id, Model model){
        // 수정할 data  가져오기
        Article articleEntity = articleRepository.findById(id).orElse(null);

        // model에 data 등록
        model.addAttribute("article", articleEntity);

        // view page 설정
        return "articles/edit";
    }

    // fetching edited data - PatchMapping 은 Form태그에서 제공 안함
    @PostMapping("/articles/update")
    public String update(ArticleForm form){
        log.info(form.toString());

        // 1. DTO를 entity로 변환
        Article articleEntity = form.toEntity();
        log.info(articleEntity.toString());

        // 2. entity를 db로 저장
        // 2-1. db에서 기존 data를 가져옴
        Article target = articleRepository.findById(articleEntity.getId()).orElse(null);
        // 2-2. 기존 data가 있다면 값을 수정 갱신함
        if(target !=null){
            articleRepository.save(articleEntity); // entity가 db로 갱신
        }



        // 3. 수정 결과 페이지로 redirect
        return "redirect:/articles/" +articleEntity.getId();
    }

}

0

홍팍님의 프로필 이미지
홍팍
지식공유자

관련 코드와 에러를 올려주면
확인해보겠다능 !

borashin님의 프로필 이미지
borashin
질문자

new.mustache

{{>layouts/header}}

<form class="container" action="/articles/create" method="post">
    <div class="mb-3">
        <label class="form-label">Title</label>
        <input type="text" class="form-control" name="title">
    </div>
    <div class="mb-3">
        <label class="form-label">Contents</label>
        <textarea class="form-control" rows="3" name="content"></textarea>
    </div>
    <button type="submit" class="btn btn-primary">Submit</button>
    <a href="/articles">Back</a>
</form>

{{>layouts/footer}}
borashin님의 프로필 이미지
borashin
질문자

Article.java

package com.example.firstproject.entity;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity //DB가 해당 객체 인식 가능
@AllArgsConstructor
@NoArgsConstructor //creating default constructor
@ToString
@Getter
public class Article {

    @Id //대표값을 지정!
    @GeneratedValue //자동 생성 어노테이션
    private Long id;

    @Column
    private String title;

    @Column
    private String content;


}

borashin님의 프로필 이미지
borashin
질문자

ArticleForm.java

package com.example.firstproject.dto;

import com.example.firstproject.entity.Article;
import lombok.AllArgsConstructor;
import lombok.ToString;

@AllArgsConstructor
@ToString
public class ArticleForm {

    private Long id;
    private String title;
    private String content;


    public Article toEntity() {

            return new Article(id, title, content);
    }
}


borashin님의 프로필 이미지
borashin
질문자

에러는 이렇게 납니다:

org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: Unique index or primary key violation: "PRIMARY KEY ON PUBLIC.ARTICLE(ID) ( /* key:1 */ CAST(1 AS BIGINT), 'red', 'apple')"; SQL statement:

insert into article (content, title, id) values (?, ?, ?) [23505-214]

 

 

red와 apple은 매번 새로운 데이터 생성하기 귀찮으니 미리 작성한 data.sql에서 입력한 id값 1의 값들입니다. 실제 15강 수업 내용은 에러 없이 끝까지 잘 실행되었습니다. id를 ArticleForm.java에 추가한 후 자동생성되던건 어떻게 되는지 궁금해서 다시 articles/new에서 데이터를 입력해보니 나온 에러입니다.

 

borashin님의 프로필 이미지
borashin
질문자

호호호호홍팍님!! 17강에서 쉬원~하게 해결해주시네요! 역시 홍팍님을 믿고 그냥 계속 강의 쭉쭈국ㄱ국들었어야했는데 제가 성급했습니다요 <3

DB가 id 자동생성하게 만드니까 해결되써용 앞으로도 신나는 강의 부탁합니다 사랑해요 감사합니다

홍팍님의 프로필 이미지
홍팍
지식공유자

😘

borashin님의 프로필 이미지
borashin

작성한 질문수

질문하기