연관관계는 총 4가지가 있습니다.

 

그 중 일대다로 일에 외래키가 존재하는 경우는 사용하지 않는 것을 추천합니다.

해당 방식은 객체와 table의 차이로 반대편 테이블의 외래키를 관리하게 되는 방법입니다.

그리하여 @JoinColumn를 사용하거나 해당 2개의 table을 연결하는 또다른 table을 구성해야합니다,

 

OneToOne

일대일 매핑으로, 외래키가 존재하는 쪽을 연관관계의 주인으로 보면 됩니다.

그래서 주인이 아닌 쪽에 mappedBy = "table명"을 작성하는 것으로 연결이 됩니다.

 

 

 

'Spring > Spring JPA' 카테고리의 다른 글

[JPA] BaeEntity - @MappedSuperclass, @EnableJpaAuditing, @DiscriminatorColumn  (0) 2023.03.12
Spring JPA  (0) 2023.03.07

DATABASE

entity는 업무에 필요한 데이터를 저장하고 관리하는 테이블을 말합니다.

속성은 entity의 한 부분으로 업무에 필요한 최소 값의 단위로 테이블의 칼럼을 말합니다.

도메인은 속성의 값, 타입, 제약사항 등에 대한 범위를 의미합니다.


Java에서 ORM 기술인 JPA를 사용하면, 도메인을 관계형 데이터베이스 테이블에 매핑할 때 공통으로 가지는 컬럼들이 있습니다. 해당 칼럼으로는 생성일자, 수정일자, 식별자 등이 있습니다.

 

@MappedSuperclass

코딩에서는 '반복'을 최대한 피하기에 객체의 입장에서 공통 매핑 정보가 필요할 때 사용합니다.

DB 테이블과 상관 없이 객체 입장에서 name이나 id 등 공통 정보는 부모 클래스에 선언하고, 속성만 상속 받아서 사용하고 싶은 경우에 사용을 하며, 매핑정보만 상속받는 Superclass라는 의미입니다.

직접 생성해서 사용할 일이 없으므로 추상 클래스로 만들어서 사용합니다.

 

* @Entity가 있는 클래스는 @Entity나 @MappedSuperclass로 지정한 클래스만 상속할 수 있습니다.

 

JPA  Auditing

Spring Data JPA에 있는 Audit 라는 시간에 대해서 자동으로 값을 넣어주는 기능을 사용합니다. 해당 기능은 영속성 컨텍스트가 생성 또는 변경되는 경우에 따라 자동으로 시간을 매핑해서 데이터베이스에 넣어주게 됩니다.

 

적용

  1. 해당 기능은 우선 build.gradle 파일에 spring-boot-starter-data-jpa를 추가하는 것으로 사용할 수 있게 됩니다.
  2. Application 파일에 @EnableJpaAuditing의 추가를 통해 Auditing 기능을 활성화시킬 수 있습니다.
  3. 공통적인 컬럼을 처리할 클래스(BaseEntity)에 @EntityListeners(AuditingEntityListener.class)를 추가합니다.
  4. 해당 클래스 변수에서는  @CreatedDate, @LastModifiedDate를 통해서 entity가 저장될 때, 시간이 자동 저장합니다.
import java.time.LocalDateTime;

@EntityListeners(AuditingEntityListener.class)
@MappedSuperclass
@Getter
@Setter
@DynamicInsert
@DiscriminatorColumn
@NoArgsConstructor
public abstract class BaseEntity {
    @CreatedDate
    @Column(updatable = false, name = "create_at", nullable = false)
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createAt;

    @LastModifiedDate
    @Column(name = "update_at")
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateAt;

    @Column(name = "status", columnDefinition = "int default 1")
    private int status = 1; // 상속관계 자동 매핑으로 자동으로 insert됨

    protected void delete() {
        this.status = 0;
    }

    // 삭제된 데이터 복구
    protected void restore() {
        this.status = 1;
    }
}

 

상세 분석

@NoArgsConstructor

: 자동으로 기본 생성자를 생성합니다.

 

@JsonFormat

: JSON 응답값의 형식을 지정하며 날짜, 형식, 키 설정, 값 포함 여부, 응답 값 순서 등 여러 형태가 있습니다.

기본적인 날짜 형식 지정으로는 @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul")가 있습니다.

 

@DynamicInsert / @DynamicUpdate

 : 삽입 또는 수정 쿼리문을 동적을 만드는 방식으로 null인 값은 제외하고(불필요한 DB 부하 감소) 쿼리문이 생성됩니다.

 

 

@DiscriminatorColumn(name="DTYPE")

: 부모클래스에 선언하며 하위 클래스를 구분하는 용도입니다.

@DiscriminatorValue("XXX")

: 하위 클래스에 선언하여, entity를 저장할 때 슈퍼타입의 구분 컬럼에 저장할 값을 지정합니다.(default = 클래스이름)

 

=> 논리 모델을 물리 모델로 구현할 방법 3가지(JOINED, SINGLE_TABLE, TABLE_PER_CLASS)의 적용에 사용하는 @Inheritance(strategy=InheritanceType.XXX)와 함께 사용됩니다. 

 

 


추가 공부

  • 칼럼 : 관계형 DB에서 사용 vs 필드 : 파일 시스템에서 사용

'Spring > Spring JPA' 카테고리의 다른 글

연관관계 설정  (0) 2023.03.25
Spring JPA  (0) 2023.03.07

JPA = Java Persistence API

자바의 ORM을 위한 표준 기술

  • Hibernate, Spring JPA, EcliplseLink 등 과 같은 구현체가 있다.
  • 이러한 구현체의 표준 인터페이스가 JPA 입니다.

ORM

자바의 객체와 관계형 DB를 맵핑하는 것

  • SQL문을 일일이 작성하지 않고 객체로 구현할 수 있도록 하는 프레임워크

JDBC

JDBC는 데이터 베이스에 접근할 수 있도록 자바를 제공하는 api로, 모든 영구성 프레임워크에는 내부적으로 plain jdbc API를 사용합니다. 해당 JDBC에는 쿼리 실행 전과 후에 많은 코드를 작성해야 하며, 로직에서 예외 처리 코드를 넣어 데이터베이스와 연결에서 안정적으로 동작할 수 있게 해야 합니다. 또한, 트랜잭션의 처리기 필요하며, 모든 코드를 반복하기 때문에 비효율적이게 됩니다.

 

그래서 spring에서는 jdbc template을 사용하면 jdbc가 데이터베이스와 연결을 열고 닫는 부분, 예외 처리, 트랜잭션 처리를 진행하여 개발자는 sql 작성과 결과 처리에 집중하는 방식으로 동작을 할 수 있습니다.
하지만 여기에도 수기로 sql 쿼리문을 직접 작성해야하는 등 문제가 있고, 이것을 해결하기 위한 것으로 JPA가 있습니다.

 

영속성

우선 영속성의 정의를 보시면, 데이터를 생성한 프로그램이 종료되어도 사라지지 않고 존재하는 데이터의 특성을 말합니다. 영속성을 가지지 않으면, 단지 메모리에 존재하므로 파일 시스템, 데이터베이스 등에 데이터를 영구적으로 저장하려고 합니다.이러한 영속성을 가진 프레임워크는 JDBC 프로그래밍의 복잡함 없이 간단한 작업만으로 데이터베이스와 연동되는 시스템을 빠르게 개발할 수 있고 안정적인 구동을 보장합니다.

 

ORM

이러한 프레임워크 중에는 ORM이 있습니다.
ORM은 데이터베이스 객체를 자바 객체로 매핑에 따라 객체 간 관계 바탕의 sql을 자동 생성하며, 관계를 객체에 반영하고자 하는 목적을 가집니다. 그리고 이러한 ORM의 영속성 API 중에는 JPA, Hibernate 등이 있습니다.

 

ORM의 영속성 API

접두사인 find, read, query, count, getby에 붙은 형태가 존재하며, 접두사에 키워드나 필드 이름을 붙이는 방식으로 생성하게 됩니다. 해당 규칙을 이용해서 작성한 메소드는 Repository 인터페이스에 선언하는 것을 통해 자동으로 구현할 수 있습니다.

 

 

자바 프로그램 구조

  • class(객체 설계도) > 메소드(이름, 파라미터, 리턴) > 문장 ;
    • 접근제어자(public) ~정적메소드(static) 리턴값(void) 이름(main) (매개변수 …) {~}
    • 자바에서는 리턴값 항상 명시
  • class 안에낸 클래스 이름과 동일한 class가 존재해야함
  • 주석문 : 코드 설명
    • /* ~ */
    • // 한줄만 무시
    • /** */ ⇒ 라이브러리로 api 문서로 만들 수 있음
  • 코드 블럭 : { } 내부, 코드블록 내 코드블록 존재하기도
    • 블럭 내 선언은 블럭외에서 사용x
  • java 프로그램은 main()부터 실행
  • 식별자 identifier
    • @#!(X) _$(O) ↔ 예약
    • 대소문자 구분 / true, false / null / 카멜 표기법
    • 숫자로 시작, 예약어, 특수문자 (x)
  • 클래스 이름 : 대문자로 시작
  • 상수 : final 모든 문자 대문자
  • 변수(초기화 필요) ↔ 클래스 멤버변수는 자동 초기화
  • 메소드 이름 : 카멜 표기법
    • int count ⇒ iCount로 타입 알 수 있게 표현하기도
    • public int iGetAge() {}

java 자료형 : 기초형 + 참조형(Class, interfaace, array, String)

  • boolean : default가 false & 논리 타입 ↔ 정수 사이 타입 변환 X
  • char : 2byte = W/u0000 unicode
  • byte, short, int, long(끝에 l/L) : byte, short는 사칙연산시 int로 변경
  • float : 끝에 반드시 f/F, double 선

진수 - 2 : 0b / 8 : 016 ~ / 16 : 0xe

지수 : E-3 = * 1000

형변환

  1. 자동으로 큰 타입
    • 피연산자 중 하나가 큰 경우, 그쪽으로
  2. 강제형 변환 → 데이터 손실 = 앞부분(뒤부터 들어감)
  • int/byte → 소수 잘려서 나옴
  • (char)0x12340041 → A(0041)

연산

산술연산

        • /(몫) %(나머지)
  • ++X, —X : 연산 후 코드 진행
  • X++, X— : 코드 후 연산

비교 연산자 <>, < =, > =, == → true/false

로직 연산자 : && and, || or, !, ^

비트 연산자 : & | ^ !

비트 shift 연산

  • a>>b a를 b번(최상위 비트로 채움
  • a>>>b : 빈 내용을 0채움
  • a<<b 빈자리 모두 0

3개의 피연산자 : (~)? 0:1

우선순위

대입 ++ +- (산술) (비트) (논리) (조건)


출력 스트림

  • 표준 : println, print
  • printf : %%(%출력) \n, %d(정수), %f(실수), %c, %s(문자열)

입력 스트림

  • System.in 키 입력 → InputStreamReader
  • 키보드 입력 받기
    • import java.util.*;
    • new Scanner(System.in);
    • sc.nextLine(); sc.next() 문자 / sc.nextInt() 숫자
    • sc에서 tab, \n 모두 동일하게 처리함

기본형의Wrapper클래스 : parseXX() 문자열을 값으로 변환

  • Integer.parseInt()
  • Double.parseDouble()

'Spring > Java' 카테고리의 다른 글

[effective java] 2. 객체 생성과 파괴  (0) 2023.08.29
[JAVA] 프로그래밍 언어, java  (0) 2023.03.10

자바 특징

  • WORA(Write Once Run Anywhere) : 한번 작성하면 어디서든 동작
  • ← 2가지 이유 : 바이트코드, JVM에서 자바 바이트 코드를 실행
  • 플랫폼 독립성 : VM 때문(vm 자체는 플랫폼에 종속)
  • 컴파일러 : java → byte 코드(VM이 아는 목적 코드) ↔ c → object 파일
    ↔ c언어는 추가로 링커 사용 : 목적코드와 라이브러리 연결

바이트 코드

  • 자바 VM이 인터프리터 방식(명령어 단위)으로 해석

자바 플랫폼 용어 & 사용

jvm < api < jre < jdk

  • jdk 자바 응용 개발 환경, 개발에 필요한 도구 포함
  • Java SE : 표준 배포판 / Java EE : 기업용 / Jave ME : 자바 마이크로 배포판 / Java FX : gui에 사용

'Spring > Java' 카테고리의 다른 글

[effective java] 2. 객체 생성과 파괴  (0) 2023.08.29
[JAVA] 프로그램  (0) 2023.03.10

1. 도메인 모델

도메인 모델과 DB 테이블 사이 매핑 처리 방식이 중요하다.

 

1-1. 트랜잭션 스크립트 패턴

All-or-Nothing 개념의 트랜잭션 처리로, 로직의 중간에 한번이라도 오류가 발생하면 모두 취소된다.

엔티티 내부에 비지니스 로직이 거의 없고, 서비스 계층에서 비즈니스 로직을 처리한다.

 

장점

  • 구현 방법이 매우 단순하다는 것이다.

단점

  • 비즈니스 로직이 복잡할 수록 난잡해진다.
  • 도메인의 분석과 설계 개념이 약해서 코드 중복 발생을 막기 어렵다.

 

1-2. 도메인 모델 패턴

엔티티 안에 대부분의 비즈니스 로직이 구성되어 있어서 객체 지향을 활용한 방법다.

비즈니스 영역의 객체를 판별 후 객체에 제공해야할 목록을 추출하고, 객체 간 관계 정립을 진행한다.

 

장점은 객체 지향에 기반한 재사용성, 확장성, 유지 보수의 편리함이 있다.

단점은 하나의 도메인 모델 구축에 많은 노력이 필요하다는 것이 있다.

 

장점

  • 객체 지향에 기반한 재사용성, 확장성, 유지 보수의 편리함이 있다.

단점

  • 하나의 도메인 모델 구축에 많은 노력이 필요하다.

 

1-3. 적용한 spring 코드 예시

@NoArgsConstructor(access = AccessLevel.PROTECTED) // 생성 메서드만으로 객체 생성을 위해

public class 객체 {

	// 속성 선언

	// 연관관계 편의 메서드

	// 생성 메서드
	public static 객체 create객체() {
		// 객체 생성
		return 객체
	}

	// 비즈니스 로직

}

2. SINGLE_TABLE

Single-Table 상속 전략은 상속 관계을 entity를 모두 묶어서 하나의 table로 만드는 방식이다.

 

사용 방법

  • @Inheritance을 통해 정의하며 SINGLE_TABLE, TABLE_PER_CLASS, JOINED 중 하나이다.
  • 사용 시, @DiscriminatorColumn에 자식 클래스를 분류할 때 사용되는 Column명을 사용해 정의해야 한다.
// 상속 하는 class
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "dtype")
// 상속 받는 class, dtype : A,B ...
@Entity
@DiscriminatorValue("B")

 

 

장점

  • 상속 관계의 entity의 관리가 편리하고 다른 entity와 관계 설정이 용이하다.
  • 높은 성능을 가진다.

단점

  • 상속 관계 entity의 모든 atrribute가 포함되어 table이 커진다.
  • 관련 없는 attribute는 모두 null 값을 가져서 not null constrain 사용에 제약이 있다.

 

 

 


참고자료

Spring에서 DB 연결시, 문제가 없던 부분이 갑자기 오류가 뜨면서 돌아가지 않는 경우가 있다.

그 중 가장 대표적인 이유를 가져와 보았다.


1. Spring과 DB 연결에서 db, user, password 등 정보 오류

  • 해결 : 접속되야하는 db의 정보에 따라서 spring 코드 수정

2. MySQL 접속 -> mysql 서비스가 로컬 컴퓨터에서 중지되었습니다.

  • 원인 : 여러개의 mysql을 동작되는 문제 or 동작 중 오류
  • 해결 : mysql 프로세스 중지 후 다시 시작
  • 참고자료 : MySQL 서버 연결 불가
 

[MySQL] 'mysql80 서비스가 로컬 컴퓨터에서 시작했다가 중지되었습니다. '

Mysql을 사용해서 개발을 하다가 이런 오류를 만나면 진짜 진짜 짜증난다ㅜㅠㅠ 저번에도 이것때문에 Mysql을 새로 설치했는데, 또다시 이런 문제가 발생해서 인터넷을 찾아봤는데, cmd 창(관리자

kumsil1006.tistory.com

3. DB 비밀번호 변경

  • 해결 : MySQL 서비스 종료 -> 비밀번호 초기화 후 다시 비밀번호 지정
    • 서비스 종료 : net stop MySql80 
    • cmd에서 SQL에 패스워드 없이 접속 가능
      • mysqld --datadir="C:\ProgramData\MySQL\MySQL Server 8.0\Data" --console --skip-grant-tables --shared-memory
      • mysql -u root
    • MySQL에서 비밀번호 초기화
      • use mysql;
      • UPDATE user SET authentication_string=null WHERE User='root';
      • select authentication_string from user;
      • flush privileges;
    • MySQL에서 비밀번호 재설정
      • ALTER USER 'root'@'localhost' IDENTIFIED WITH caching_sha2_password BY '123456';
      • use mysql;
      • select authentication_string from user;
    • MySQL 프로그램 재시작
  • 참고자료 : mysql 비밀번호 초기화
 

[MySQL] mysql root 비밀번호 초기화 (mysql 8)

ㅎㅎ 인코딩 설정하다가 뭔가가 꼬여, 비밀번호 초기화가 필요했다. ① 설정 > 시스템에서 Mysql80 시스템을 종료하거나 cmd를 관리자 권한으로 열어 >> net stop MySql80 ② mysql이 program Files에, Program Dat

sseyeon.tistory.com

 

'Spring > DB' 카테고리의 다른 글

[DB] 다양한 DB 비교  (0) 2023.10.04
[DB] 트랙잭션과 인덱스  (0) 2023.08.28
[DB] PostgreSQL과 MySQL  (0) 2023.08.08
[멋사] DB 연동  (0) 2023.04.06

start

해당 내용은 spring 프로젝트를 진행하면서 제가 만난 오류 코드이며, 해당 내용에 대해서 원인과 해결방안을 작성해 보았습니다.

 

 

📌Spring 기초 오류

 

8080 포트로 미동작 (APPLICATION FAILED TO START)

  • 원인
    • 이미 사용 중(Web server failed to start. Port 8080 was already in use.)
  • 이유
    • 프로그램 실행 전 미처 확인하지 못함
  • 해결
    1. cmd에 사용중인 port 리스트 출력(netstat -a -o)
    2. 해당 PID 죽이기

Whitelabel Error Page

  • 문제
    • lombok 미연결
  • 해결
    • @controller 위에 @ResponseBody 추가로 해결
    - @RestController = (@Controller + @ResponseBody) 조합

        → RESTful 웹 서비스를 보다 쉽게 개발할 수 있도록


    - controller 역할 : model 객체 만들어 데이터 담고, view 찾는 것

    ↔ @RestController : 객체만 반환, 객체 데이터는 JSON/XML 형식으로 HTTP 응답에 담음

    - 차이 : **@RestController을 표시하면 모든 메소드가 뷰 대신 객체로 작성**  
  - 참고자료
    > [@Controller와 @RestController의 차이점](https://dncjf64.tistory.com/288)

 


DefaultHandlerExceptionResolver

    • MissingServletRequestParameterException
      • 문제
        • Resolved [org.springframework.web.bind.MissingServletRequestParameterException: Required request parameter 'name' for method parameter type String is not present]

 


APPLICATION FAILED TO START

  • 문제
    • The bean 'postService', defined in class path resource [hello/hellospring/SpringConfig.class], could not be registered. A bean with that name has already been defined in file [C:\Users\1212g\Downloads\hello-spring\out\production\classes\hello\hellospring\service\PostService.class] and overriding is disabled.
  • 해결
    • 빈 등록을 중복하여 발생하는 문제
    • @Service어노테이션을 삭제(주석)처리 or SpringConfig.class에서 Service등록(@Bean)을 제거

servlet

  • 문제
    • Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
  • 해결
    • private으로 선언만 하는 부분에 final까지 추가

hibernate

  • 문제
    • detached entity passed to persist: hello.hellospring.domain.Post
  • 해결
    • 엔티티 클래스에 @Id를 부여한 필드에 @GeneratedValue를 작성하여 AUTO, SEQUENCE, IDENTITY 전략 등 데이터베이스에게 key 값을 자동 생성하도록 하는 전략을 선택했으나, 추가로 ID 값을 만들어서 DB에 전송한 경우
    • → 해당 추가 ID 넣는 부분 제거

원본 : Spring Boot 오류 해결

'Spring > error' 카테고리의 다른 글

Security 사용하는 페이지 접근 오류  (0) 2023.03.06
UnsupportedClassVersionError  (0) 2022.07.05

layout: post
title: Security 페이지 접근 오류
subtitle: 회원가입 기능 개발 중 발생한 오류 정리
categories: spring
tags: [flavor-spot-finder, security, spring, study]


issue

📌 Security 주의사항

이전에 자주 사용되던 'WebSecurityConfigurerAdapter'는 Spring Security 5.7.0-M2부터 더이상 사용되지 않습니다.

대신 Spring Security는 'SecurityFilterChain'을 사용하기를 권장하고 있습니다.

SecurityFilterChain

WebSecurityConfigurerAdapter의 'webSecurityCustomizer()'와의 차이점

: SecurityFilterChain을 반환하고 빈으로 등록함으로써 컴포넌트 기반의 보안 설정이 가능합니다.

1. 문제 발생 원인

build.gradle에서 dependencies로 "org.springframework.boot:spring-boot-starter-security"를 사용했을 때

Security에 의해 자동으로 localhost:8080/login으로 페이지가 넘어가서 먼저 username과 password를 통해 권한 확인을 받아야 하는 경우

위 구조에서 id = user & password = (서버에 출력되는 password 값)을 사용해도 "권한이 거부되었다"는 메시지가 뜨는 경우

권한 거부 메시지

2. 문제 해결 방법

    public class SecurityConfig {
      @Bean
      public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
          return httpSecurity
                  .httpBasic().disable()
                  .csrf().disable()
                  .cors().and()
                  .authorizeRequests()
                  .antMatchers("/api/**").permitAll()
                  .antMatchers("/api/users/new-user", "/api/users").permitAll()
                  .and()
                  .sessionManagement()
                  .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                  .and()
                  .build();
      }
  }

'Spring > error' 카테고리의 다른 글

Spring Boot 기초 오류  (0) 2023.03.06
UnsupportedClassVersionError  (0) 2022.07.05

+ Recent posts