Web/Spring

Spring boot REST API, H2 DB(sql), JPA (1) + Entity, Lombok 생성자 에러

dev_sr 2020. 9. 21. 13:23

이번에 따라한 블로그 글

 

스프링 부트 (Spring boot) 기반으로 JPA, Lombok, H2 를 이용하여 REST API 구현

스프링 부트 (Spring boot) 기반으로 JPA, Lombok을 사용하여 H2 데이타베이스에 임시 데이타를 기록한뒤 이를 읽고 리턴하는 REST API를 구현하는 예제를 작성해본다.

skypacific.github.io

그대로 따라해보고 404..실패했지만 알게된 게 많아서 정리해봄 

 

 

먼저 jpa란 

 

[JPA] JPA란 - Heee's Development Blog

Step by step goes a long way.

gmlwjd9405.github.io

자바 기반 ORM 인터페이스 모음

jdbc나 sql를 따로 작성할 것 없이 내부에서 DB와 통신한다고 한다.

객체 중심 개발을 가능하게 해주므로 Entity 지정이 필수라고 한다.

 

 

 

Entity 관련

테이블을 객체단위로 지정해줌

 

[Spring Data] Entity

Entity.. 엔티티란 한마디로 경량의 영속성 도메인 오브젝트입니다. 여기서 또 영속성이란 메모리영역이 아닌 물리 데이터 저장공간(database)에 저장되어 애플리케이션이 종료되더라도 데이터가 ��

chan180.tistory.com

 

 

 

 

H2 Database란 자바 기반의 오픈소스 관계형 데이터베이스 관리시스템 (RDBMS)라고 한다.

표준 sql을 지원하고 매우 가볍고 빠르기 때문에 개발단계에서 많이 사용된다고 한다.

일단 sql이니깐 사용해본다

 

 

[H2DB] H2 Database란? H2DB 설치 방법

H2DB H2DB는 자바 기반의 오픈소스 관계형 데이터 베이스 관리 시스템(RDBMS )입니다. H2DB는 서버(Server) 모드와 임베디드(Embedded) 모드의 인메모리 DB 기능을 지원합니다. 물론 디스크 기반 테이블을 ��

dololak.tistory.com

 

 

 

JPA와 H2 DB 가 필요하므로 만들 때 그냥 같이 설치하기로 함

만들고 pom.xml에서 디펜던시 추가를 해도 됨

 

일단 코드

model

package com.jpaTest.jpaTest.model;

import lombok.Data;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import javax.persistence.Entity;
import javax.persistence.Id;


@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity	//경량의 영속성(DB에 저장, 안사라짐) 도메인 오브젝트->하나의 테이블로 생각
public class Product {	//실제 DB테이블과 매칭될 클래스,객체단위의 테이블이 되어 관리함
	@Id //키값이 될 속성 값의 위에 달아줌
	int id;
	String title;
	double price;
	int inventory;//재고 수량
}

 

 

repository

package com.jpaTest.jpaTest.repository;

import com.jpaTest.jpaTest.model.Product;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;


@Repository //테이블(Entity)을 관리
public interface ProductRepository extends JpaRepository<Product, Integer> {
	//제네릭 타입 첫번째 인자엔 Product, 두번째(ID)는 키 타입 Integer
	//두번째 타입엔 원시타입인 int, long 을 넣으면 안되고
	//Wrapper 클래스인 Integer, Long등을 사용하여야 한다.
	//Wrapper 클래스: 기본 데이터 형과 관련된 여러 기능들을 묶어 놓은 클래스
	//ex) Number 클래스(부) -> Integer 클래스(자) -> int
}

 

 

controller

package com.jpaTest.japTest.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.jpaTest.jpaTest.model.Product;
import com.jpaTest.jpaTest.repository.ProductRepository;

@RestController
public class Controller {

	@Autowired
	private ProductRepository productRepository;
	
	@RequestMapping("/product")
	public List<Product> getProducts(){
		System.out.println("출력");
		return productRepository.findAll();	//돌아가는 거 보고 엔티티 지워보기
	}
	
	@RequestMapping("/product/{id}")
	public Product getProductById(@PathVariable("id") int id) {
		return productRepository.findById(id).get();
	}
}

 

 

진입점에서 객체 생성, 초기화해서 넣어주는데 

여기서 lombok이 제대로 설치되지 않아서 생성자가 없다고 에러가 발생했음.

package com.jpaTest.jpaTest;

import org.springframework.boot.SpringApplication;
import com.jpaTest.jpaTest.model.Product;
import com.jpaTest.jpaTest.repository.ProductRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;


@SpringBootApplication
public class JpaTestApplication {

	@Autowired	//자동 의존성 주입
	private ProductRepository productRepository;
	
	//이 프로젝트에서는 H2 db가 같이 실행되는데 샘플 데이터가 없기 때문에
	//어플리케이션 실행시 샘플 데이터를 넣어주기 위한 것 
	//ApplicationRunner 객체를 생성해 놓으면 어플리케이션 실행 시에 자동으로 
	//run메소드가 실행됨
	@Bean	//ApplicationRunner Bean을 자동생성해주는 메서드인데, Bean이 있어야 인식
	public ApplicationRunner applicationRunner() {
	    return args -> {
	        productRepository.save(new Product(1, "iPad 4 Mini", 500.01, 2));
	        productRepository.save(new Product(2, "H&M T-Shirt White", 10.99, 10));
	        productRepository.save(new Product(3, "Charli XCX - Sucker CD", 19.99, 5));
	    };
	}
	
	
	public static void main(String[] args) {
		SpringApplication.run(JpaTestApplication.class, args);
	}

}

 

 

lombok에러 해결 (lombok은 디펜던시로 설치되지 않는다 ㅎㅎㅎㅎㅎ)

구글에 sts4 lombok 설치를 검색

 

[lombok] eclipse(STS)에 lombok(롬복) 설치

구글링을 해봐도 속시원하게 내 문제를 해결해준 글이 없어서 직접 정리 0. 내 환경 - eclipse : STS 3.8.3 - lombok : 1.16.10 1. 프로젝트의 pom.xml에 lombok 의존성 추가 (필요한 버전이 있다면 버전을 표시)..

countryxide.tistory.com

블로그에서 가르쳐준대로 다시 설치 ..

 

lombok이 제대로 설치되어야 outline에 getter, setter, constructor 가 생긴다..

이전엔 속성만 있고 나오질 않았음 ㅠㅠ

그래서 계속 생성자가 없다고 에러가 났음

 

 

순서도 중요한게 AllArgConstructor는 변수를 다 받는 생성자이고

NoArgsConstructor는 변수를 전혀 받지 않는 생성자임

 

Jpa에선 entity에 기본생성자가 있어야한다고 함 

그래서 NoArgConstructor 를 써줘야함

없다면 실행시 아래와 같은 에러가 생김

No default constructor for entity jpa

 

그런데 변수를 안받는 생성자가 가장 밑에 있을 경우

NoArgConstructor 만 적용이 되어서 생성자가 없다고 에러가 생긴다..ㅋㅋㅋ

 

AllArgConstructor를 밑에 써보니 에러 탈출은 성공함.

 

 

 

 

마지막으로 디버그 에러

 

시작

Spring Boot 설정 관련하여 초기 셋팅해 주는 URL : https://start.spring.io/ 1. 메이븐 설정 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.ap..

kamsi76.tistory.com

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.

 

어차저차 실행하면 이런 버그가 또 나오는데 찾아보니

run->run configuration에서 arguments 로 가서 --debug를 써주고 apply해주면 사라진다

 

대신에 저 오류를 해결하면 이렇게 무슨 어노테이션이 매칭됐고 안됐고를 쭉 보여주는데

가독성이 진짜 떨어진다..

그래도 디버그는 금방 해결했는데

Lombok과 저 생성자 어노테이션 때문에 3시간은 넘게 날린 것 같다..

 

 

그리고 404만 떠서 실패했다

매핑이 안된다는데 스프링 공부한지 얼마 안되어서 그런지 어디서 문제가 생기는 건지 잘 모르겠음..

 

 

프론트하고 다른 예제 찾아봐야지 ㅠㅠ