Skip to content

Conversation

@Eundms
Copy link

@Eundms Eundms commented Dec 7, 2025

  1. 1:N ๊ด€๊ณ„ - Session : Registration (์ˆ˜๊ฐ•์‹ ์ฒญ)

๋„๋ฉ”์ธ ๋ชจ๋ธ:
Session (1) โ”€โ”€โ”€โ”€ (N) Registration

ํ…Œ์ด๋ธ” ์„ค๊ณ„:
session (id, course_id, term, ...)
registration (id, session_id, student_id, enrolled_at) -- FK๋กœ session_id ์ฐธ์กฐ

๊ณ ๋ฏผํ•œ ๋ถ€๋ถ„:

  • Session ์กฐํšŒ ์‹œ findRegistrationsBySessionId()๋กœ ์—ฐ๊ด€๋œ Registration๋“ค์„ ์กฐํšŒํ•ด์„œ Registrations ๊ฐ์ฒด๋กœ ์กฐ๋ฆฝ
  • maxCapacity ์ •๋ณด๋Š” Session ํ…Œ์ด๋ธ”์— ์ €์žฅํ•˜๊ณ , Registrations ์ƒ์„ฑ ์‹œ ์ „๋‹ฌ:
    Registrations registrations = findRegistrationsBySessionId(id, entity.getMaxCapacity());
  1. 1:1 ๊ด€๊ณ„ - Session : SessionCoverImage (์ปค๋ฒ„ ์ด๋ฏธ์ง€)

๋„๋ฉ”์ธ ๋ชจ๋ธ:
Session (1) โ”€โ”€โ”€โ”€ (1) SessionCoverImage

ํ…Œ์ด๋ธ” ์„ค๊ณ„:
session (id, ...) -- ์ด๋ฏธ์ง€ ์ •๋ณด๋ฅผ ํฌํ•จํ•˜์ง€ ์•Š์Œ
session_cover_image (id, session_id, width, height, extension, capacity) -- FK๋กœ session_id ์ฐธ์กฐ

๊ณ ๋ฏผํ•œ ๋ถ€๋ถ„:

  • 1:1์ด์ง€๋งŒ ๋ณ„๋„ ํ…Œ์ด๋ธ”๋กœ ๋ถ„๋ฆฌ (Session ํ…Œ์ด๋ธ”์— ์ž„๋ฒ ๋”ฉํ•˜์ง€ ์•Š์Œ)
  • ๋ถ„๋ฆฌํ•œ ์ด์œ  :
    • ์ด๋ฏธ์ง€ ๊ด€๋ จ ํ•„๋“œ๊ฐ€ ๋งŽ์•„์„œ (width, height, extension, capacity)
    • Session ํ…Œ์ด๋ธ”์˜ ์ฑ…์ž„์„ ์ค„์ด๊ธฐ ์œ„ํ•ด
    • ์ด๋ฏธ์ง€๊ฐ€ ์—†์„ ์ˆ˜๋„ ์žˆ๋Š” ๊ฒฝ์šฐ (null ํ—ˆ์šฉ)
  • Session ์กฐํšŒ ์‹œ findCoverImageBySessionId()๋กœ ์กฐํ•ฉ:
    SessionCoverImage coverImage = findCoverImageBySessionId(id);
    return SessionMapper.toDomain(entity, registrations, coverImage);
  1. ๊ฐ’ ๊ฐ์ฒด(VO) ์ฒ˜๋ฆฌ - Flatํ•˜๊ฒŒ ์ €์žฅ

SessionType (FreeType/PaidType) ์ฒ˜๋ฆฌ:
session (
type varchar(10), -- 'FREE' or 'PAID'
max_capacity int, -- PaidType์˜ maxCapacity
tuition_fee bigint -- PaidType์˜ tuitionFee
)

Mapper์—์„œ ๋ณต์›:
if ("FREE".equals(entity.getType())) {
type = new FreeType(registrations);
} else {
type = new PaidType(entity.getTuitionFee(), registrations);
}

  1. Entity/Mapper ํŒจํ„ด ๋„์ž…

๊ตฌ์กฐ:
Domain Object โ†โ†’ Entity โ†โ†’ DB
โ†‘ โ†‘
โ””โ”€โ”€ Mapper โ”€โ”€โ”˜

  • Entity: DB ํ…Œ์ด๋ธ”๊ณผ 1:1 ๋งคํ•‘๋˜๋Š” ์ˆœ์ˆ˜ ๋ฐ์ดํ„ฐ ๊ฐ์ฒด
  • Mapper: Domain โ†” Entity ๋ณ€ํ™˜ ์ฑ…์ž„
  • Domain ๊ฐ์ฒด๋Š” DB ๊ตฌ์กฐ๋ฅผ ๋ชจ๋ฅด๊ณ , Entity๋Š” ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ๋ชจ๋ฆ„

ํ•ต์‹ฌ ์„ค๊ณ„ ๊ฒฐ์ • ์š”์•ฝ

๊ด€๊ณ„ ๋„๋ฉ”์ธ ํ…Œ์ด๋ธ” ์ „๋žต ์กฐํšŒ ์ „๋žต
1:N Session:Registration ๋ณ„๋„ ํ…Œ์ด๋ธ” + FK ์กฐํšŒ ์‹œ joinํ•ด์„œ ์กฐ๋ฆฝ
1:1 Session:CoverImage ๋ณ„๋„ ํ…Œ์ด๋ธ” + FK ์กฐํšŒ ์‹œ ์ถ”๊ฐ€ ์ฟผ๋ฆฌ
VO (๋‹คํ˜•์„ฑ) SessionType ๋‹จ์ผ ํ…Œ์ด๋ธ”์— type ์ปฌ๋Ÿผ type์— ๋”ฐ๋ผ if-else ์ƒ์„ฑ
VO (๋‹จ์ˆœ) SessionPeriod, Term Session ํ…Œ์ด๋ธ”์— flat ์ €์žฅ ์กฐํšŒ ์‹œ VO๋กœ ๊ฐ์‹ธ์„œ ์ƒ์„ฑ

Copy link
Contributor

@javajigi javajigi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๊ธฐ์กด์˜ ๋„๋ฉ”์ธ ๊ฐ์ฒด๋ฅผ ์œ ์ง€ํ•˜๋ฉด db ๋งคํ•‘ ๋„˜ ์ž˜ ํ–ˆ๋„ค์š”. ๐Ÿ’ฏ
Entity/Mapper ํŒจํ„ด์„ ๋„์ž…ํ•ด ๋„๋ฉ”์ธ ๊ฐ์ฒด๊ฐ€ db ์—ฐ๊ฒฐ๋กœ ์ธํ•ด ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š๋„๋ก ์ตœ์†Œํ•œ ๊ฒƒ๋„ ์ธ์ƒ์ ์ด๋„ค์š”.
Entity ๊ฐ์ฒด์˜ ์‚ฌ์šฉ์— ๋Œ€ํ•œ ํ”ผ๋“œ๋ฐฑ์ด ์žˆ์–ด ๋‚จ๊ฒจ๋ดค์–ด์š”.
์€์ •๋‹˜์€ ์–ด๋–ป๊ฒŒ ์ƒ๊ฐํ•˜๋Š”์ง€ ๊ฒฐ๊ณผ๊ฐ€ ๊ถ๊ธˆํ•˜๋„ค์š”.

import java.util.Collections;
import java.util.List;

public class Registrations {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๐Ÿ‘

import java.time.LocalDate;
import java.time.LocalDateTime;

public class SessionEntity {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๋„๋ฉ”์ธ ๊ฐ์ฒด์— db ๋งคํ•‘ ๊ด€๋ จ ์ž‘์—…์„ ์˜ค์—ผ ์‹œํ‚ค์ง€ ์•Š๊ธฐ ์œ„ํ•ด Entity ์ถ”๊ฐ€ ๐Ÿ‘

import nextstep.courses.domain.registration.Registrations;
import nextstep.courses.infrastructure.entity.RegistrationEntity;

public class RegistrationMapper {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๋งค๋ฒˆ Mapper๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด ๋ฒˆ๊ฑฐ๋กญ๋‹ค๋ฉด https://mapstruct.org/ ์™€ ๊ฐ™์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ์„ ๊ณ ๋ คํ•ด ๋ณด๋Š” ๊ฒƒ๋„ ๋ฐฉ๋ฒ•์ผ ์ˆ˜ ์žˆ๊ฒ ๋‹ค.

Comment on lines 23 to 27
Session session = sessionRepository.findById(payment.getSessionId());
session.validateEnroll(payment.getAmount());

Registration registration = new Registration(payment.getSessionId(), payment.getNsUserId());
registrationRepository.save(registration);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์ด ๋ฏธ์…˜์˜ ๊ฐ์ฒด ์„ค๊ณ„์—์„œ ์ˆ˜๊ฐ• ์‹ ์ฒญ ๊ฐ€๋Šฅ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ด ๋ณต์žก๋„๊ฐ€ ๊ฐ€์žฅ ๋†’์€ ๋ถ€๋ถ„์ด์ด๋‹ค.
์ด ๋ถ€๋ถ„์€ Session ๊ฐ์ฒด ๋‚ด์— ๋‘๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์•„๋ž˜์™€ ๊ฐ™์ด Session์„ ํ†ตํ•ด ์ˆ˜๊ฐ•์‹ ์ฒญ์— ํ•„์š”ํ•œ ๊ฐ์ฒด๋ฅผ ์•„๋ž˜์˜ Enrollment์™€ ๊ฐ™์€ ๊ฐ์ฒด๋กœ ์ƒ์„ฑํ•œ ํ›„ ์œ„์ž„ํ•จ์œผ๋กœ์จ ๋ณต์žก๋„๋ฅผ ๋‚ฎ์ถ”๋Š” ๋ฐฉ์‹์œผ๋กœ ์ ‘๊ทผํ•ด ๋ณด๋Š” ๊ฒƒ์€ ์–ด๋–จ๊นŒ?

    Session session = ...
    List<Student> students = ...
    Enrollment enrollment = session.enrollment(students);
    Student student = enrollment.enroll(user);
    enrollmentRepository.save(student.getUserId(), student.getSessionId());

์œ„ ์ฝ”๋“œ์—์„œ ๋ฆฌํŒฉํ„ฐ๋ง ํžŒํŠธ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ๋ถ€๋ถ„์ด ์žˆ๋‹ค๋ฉด ๋ฆฌํŒฉํ„ฐ๋งํ•ด ๋ณธ๋‹ค.
์œ„ ์ฝ”๋“œ์—์„œ Student๋Š” ์€์ •๋‹˜ ๊ตฌํ˜„ํ•œ ์ฝ”๋“œ์˜ Registration๊ณผ ๊ฐ™์Œ

Comment on lines 23 to 27
Session session = sessionRepository.findById(payment.getSessionId());
session.validateEnroll(payment.getAmount());

Registration registration = new Registration(payment.getSessionId(), payment.getNsUserId());
registrationRepository.save(registration);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Entity ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์žˆ๋Š”๋ฐ Repository์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๋Š”?

Suggested change
Session session = sessionRepository.findById(payment.getSessionId());
session.validateEnroll(payment.getAmount());
Registration registration = new Registration(payment.getSessionId(), payment.getNsUserId());
registrationRepository.save(registration);
SessionEntity session = sessionRepository.findById(payment.getSessionId());
List<Registration> registrations = registrationRepository.findBySessionId(payment.getSessionId());
Enrollment enrollment = session.enrollment(registrations);
enrollment.enroll(payment);

์œ„์™€ ๊ฐ™์ด Repository์— ๊ฐ’์„ ์ „๋‹ฌํ•˜๊ณ  ์กฐํšŒํ•  ๋•Œ Entity๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์–ด๋–ป๊ฒŒ ์ƒ๊ฐํ•˜๋‚˜?

Copy link
Author

@Eundms Eundms Dec 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(๋ฐ”๊ฟ”์•ผ์ง€ ํ•˜๊ณ  ์žŠ์–ด๋ฒ„๋ ธ์Šต๋‹ˆ๋‹ค)
SessionRepository๋Š” ๋„๋ฉ”์ธ ๋ ˆ์ด์–ด์— ์žˆ์œผ๋ฏ€๋กœ Session์œผ๋กœ ๋ฐ›๋Š”๊ฒŒ ๋งž๋Š” ๊ฑฐ ๊ฐ™๊ณ 
๊ตฌํ˜„์ฒด๋Š” ์ธํ”„๋ผ ๋ ˆ์ด์–ด์— ์žˆ์œผ๋ฏ€๋กœ SessionEntity๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค

Copy link
Contributor

@javajigi javajigi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ํ”ผ๋“œ๋ฐฑ ๋ฐ˜์˜ ๋„˜ ์ž˜ ํ–ˆ๋„ค์š”. ๐Ÿ’ฏ
์ถ”๊ฐ€๋กœ ํ•œ๋ฒˆ ๊ณ ๋ฏผํ•ด ๋ดค์œผ๋ฉด ํ•˜๋Š” ๋ถ€๋ถ„์ด ์žˆ์–ด ํ”ผ๋“œ๋ฐฑ ๋‚จ๊ฒผ์œผ๋‹ˆ ์ด๋ฒˆ ๊ธฐํšŒ์— ํ•œ๋ฒˆ ๊ณ ๋ฏผํ•ด ๋ณด๋ฉด ์ข‹๊ฒ ์Šต๋‹ˆ๋‹ค.

}

public Enrollment(SessionState state, SessionType type) {
private final Session session;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Session์œผ๋กœ ์˜์กด ๊ด€๊ณ„๋ฅผ ๊ฐ€์ง€๋‹ค๋ณด๋‹ˆ Enrollment ์ƒ์„ฑ์—๋„ ์–ด๋ ค์›€์ด ์žˆ์„ ๊ฒƒ ๊ฐ™๋‹ค.
์˜์กด ๊ด€๊ณ„๋ฅผ ๋Š๊ณ , 'long sessionId'๋งŒ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์€ ์–ด๋–จ๊นŒ?
๊ฐ์ฒด์˜ ์˜์กด ๊ด€๊ณ„๋ฅผ ๋ฌด์กฐ๊ฑด์œผ๋กœ ๊ฐ€์ ธ๊ฐ€๋Š” ๊ฒƒ์ด ์ข‹์€ ๊ฒƒ์€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฒˆ ๊ธฐํšŒ์— ์–ด๋А ์‹œ์ ์— ์˜์กด ๊ด€๊ณ„๋ฅผ ๋Š๋Š” ๊ฒƒ์ด ์ข‹์„์ง€ ๊ณ ๋ฏผํ•ด ๋ณด๋Š” ์—ฐ์Šต๋„ ํ•ด๋ณด๋ฉด ์ข‹๊ฒ ๋‹ค.

@javajigi javajigi merged commit c0e9f4e into next-step:eundms Dec 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants