기본 개념들을 다시 학습하는 시간을 거치고 나서 오늘은 Spring Data JPA의 개념에 대해 학습하고 직접 타이핑해보고, Postman을 통해 오류없이 진행되는지 확인하는 과정을 거쳤다. 그 중에서 사소한 실수와 처음 경험해보는 환경에 대해 익숙해지고 실수를 반복하지 않도록 하기 위해 정리하고 넘어가보고자 한다.
오늘은 학습 과정에서 어떤 특이사항과 해결과정이 있었는지도 함께 담아 내보고자 한다.
✅ 오늘 학습한 내용
JPA란?
: 객체 지향 프로그래밍 언어인 Java와 관계형 데이터베이스 간의 패러다임 불일치 문제를 해결하여 데이터베이스 작업을 객체 지향적으로 수행할 수 있도록 지원하는 ORM. SQL을 직접 작성하지 않고도 객체 조작을 통해 DB작업을 수행할 수 있도록 표준화된 인터페이스를 제공
Entity란?
: Entity는 데이터베이스의 테이블과 1:1로 대응되는 Java 클래스
- 데이터베이스 테이블의 구조를 Java 클래스로 표현
- 테이블의 행(row)을 객체(object)로 매핑
- ORM(Object-Relational Mapping)의 핵심
📚 관련 어노테이션 정리
@Entity : 이 클래스가 JPA 엔티티임을 선언
@Entity
public class Member {
// 클래스 내용
}
💡 클래스 이름대로 실제 데이터베이스 테이블과 매핑됨. 위의 경우 member 테이블이 된다.
@Table : 엔티티와 매피할 테이블의 정보를 지정
@Entity
@Table(name = "members")
public class Member {
//클래스 내용
}
💡 필수는 아니지만, 웬만하면 클래스의 복수형으로 적어주는 것이 좋음. 예약어로 사용하게 되면 용어가 겹쳐 에러가 날 수 있기 때문
@Id, @GeneratedValue
- @Id : 기본 키(Primary Key) 매핑
- @GeneratedValue : 기본 키 자동 생성 전략 지정. MySQL에서는 IDENTITY 전략을 사용
@Entity
@Table (name = "members")
public class Member {
@Id
@GeneratedValue(startegy = GenerationType.IDENTITY)
private Long id;
// ...
}
@Column
- 필드와 컬럼 매핑 정보 지정
- @Column의 속성
- name : 컬럼명
- length : 문자 길이 제약조건
- nullable : null 허용 여부
- unique : 유니크 제약조건
@Entity
@Table(name = "members")
public class Member {
@Id
@GeneratedValue (starategy = GenerationType.IDENTITY)
private Long id;
@Column(unique = true, nullable = false)
private String email;
}
데이터베이스 테이블과 엔티티 매핑
- 데이터베이스 테이블
CREATE TABLE users (
id BIGINT AUTO_INCERMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
email VARCHAR(255) NOT NULL UNIQUE,
address VARCHAR(255)
);
- 엔티티 클래스
@Getter
@Entity
@Table(name = "users")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(length = 50, nullable = false)
private String name;
@Column(unique = true, nullable = false)
private String email;
private String address;
}
💡@Column 기본 설정
- @Column의 속성으로 length 값을 정해주지 않는다면 255로 설정됨 (default : 255)
→ email의 length가 2555로 설정됨 - @Column을 아예 사용하지 않는다면 length는 255, nullable=true로 정해짐
→ address의 length는 255로 설정되었고, nullable=true로 설정
💡@NoArgsConstructor (access = AccessLevel.PROTECTED)가 있어야 하는 이유?
: @NoArgsConstructor는 Lombok의 기능으로, 기본 생성자를 만들어 줌. 그리고 (access = AccessLevel.PROTECTED) 속성은 기본 생성자의 접근 제어자를 protected로 하여 외부에서의 접근을 막음
즉, @NoArgsConstructor(acess = AccessLevel.PROTECTED)는 코드로 본다면
protected User() { // protected 기본 생성자
}
와 같음. 이를 편하게 Lombok으로 생성한 것
기본적으로 JPA 개념에 대해 학습해 나아갔고 그를 통한 CRUD 실습 과정을 거쳤다.
위의 내용들을 다시한번 정리하고 익숙해지기 위해서 다음과 같은 방법으로 생각하자!
@Getter
@Entity
@Table (name = "xxx")
@NoArgsConstructor (access = AccessLevel.PROTECTED)
public class Xxx {
@Id
@GeneratedValue (strategy = GenerationType.IDENTITY)
private Long Id;
// ...
}
Entity 클래스 코드를 작성할 때에는
- @Getter
- @Entity
- @Table
- @NoArgsConstructor(access = AccessLevel.PROTECTED)
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
는 무조건 적고 시작할 것!
❗어떤 문제가 있었는지
- ① 8080 점유 현상 (새로운 예제를 실행하고자 할때 8080이 이미 선점되어 해당 포트에서 실행할 수 없는 현상)
- ② 기본 CRUD (Create/Read/Update/Delete) 패키지와 클래스파일, 인터페이스 파일 배치 과정에서 어플리케이션 실행을 진행했을 때 컴파일 이후 런타임 오류가 발생함(실행상태가 유지되지 않고 에러메세지와 함께 종료됨)
- ③ JPA Auditing을 DTO에 구현하는 과정에서 Request쪽에 추가하게 되며 오류가 발생 ( 자동으로 시간을 불러오게 하는게 아니라 null 값이 반환되는 현상)
📝 내가 시도해본 것들
- ① 점유하고 있는 프로세스 번호를 찾아 강제로 kill 하여 실행에 문제가 없도록 8080 포트를 확보
- ② 콘솔창 기반으로 오류 위치를 찾고자 하였고, 오류 메세지가 안내하는 오류의 내용이 무엇인지 확인하고자 하였음
- 작성한 각 파일의 오탈자는 없는지, 사소한 실수부터 점검을 진행
- 각 Request, Response dto에 해당 Auditing 을 getter, setter 을 추가 수정하려 했음
💡 어떻게 해결했는지
- ① 사실 kill 하는 형태의 방식은 좋은 해결방식이 아님, 문제는 이전 프로젝트에서 수기로 Stop 하지 않은 상태에서 새로운 프로젝트 파일을 열고, DisConnect 하는 과정에서 프로세스는 지속적으로 실행상태에 멈춰있고 그 포트를 향해 새로운 실행요청을 넣으려 하니 발생했던 이슈였음.
- ② application.properties의 데이터베이스명이 오탈자가 발생함에 따라 참조하는 데이터베이스에서 오류가 발생, 정확하게 실행됮 않는 부분을 점검하였고, 생성한 데이터베이스명으로 올바르게 수정한 후 정상 실행되는 것을 확인
- ③ Auditing 기능 자체에 자동으로 최초 생성시간, 변형된 시간을 기록하는 기능을 내재하고 있음. 이에 따라 Request로는 해당 값들을 넣을 필요가 전혀 없고, Response의 조건에 따라 해당 값들을 불러올 수 있도록 설정하면 되었음 (어노테이션의 개념을 다시한번 짚어볼 것)
👍 무엇을 새롭게 알았는지
이전에도 비슷한 실습과정에 있어서 포트 점유 현상을 지속적으로 경험했고, 원인을 명확하게 짚고 넘어가지 않아 이번 문제점이 발생했을 때에도 문제점을 찾아봐야 하는 상황이 있었음. 반드시 실행과 종료까지가 한 몸으로 움직일 수 있게끔 리마인드 하는 습관을 거쳐 나아가야겠다고 생각했음.
아직 익숙하지 않은 부분이 너무 많아 반복 숙달하며 손과 머리가 익혀갈수 있도록 해 나아갈 필요가 있음
'Spring' 카테고리의 다른 글
| [Spring] 3 Layer Architecture 개념 정리 (0) | 2025.10.17 |
|---|