티스토리 뷰
1️⃣ 기본 개념
✅ @ElementCollection
- JPA에서는 일반 엔티티가 아닌 값 타입(예: List<String>, Set<Enum> 등)을 저장할 때 사용합니다.
- 별도의 테이블을 생성하여 관리합니다.
- 예를 들어, 사용자(User)가 여러 개의 역할(Role) 을 가진다면, 역할을 따로 테이블에 저장해야 합니다.
✅ fetch = FetchType.EAGER
- EAGER(즉시 로딩) : User 엔티티를 가져올 때 즉시 함께 가져옴
- 기본적으로 @ElementCollection은 LAZY이므로 명시적으로 EAGER로 설정하면 즉시 로딩됨
2️⃣ 예제 코드로 이해하기
👎 @ElementCollection 없이 일반적인 필드로 저장하면?
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String email;
private String roles; // 🚨 여러 개의 역할을 `String`으로 저장하면 문제 발생
// 예: "ROLE_USER,ROLE_ADMIN" 문자열로 저장하면 유지보수가 어려움
}
✅ 문제점:
- roles를 String으로 저장하면 배열처럼 다루기 어려움
- 새로운 역할이 추가될 때 수정이 어렵고 유지보수가 힘듦
- SQL 검색이 불가능 (WHERE roles LIKE '%ADMIN%' 같은 쿼리는 비효율적)
👍 @ElementCollection을 사용하면?
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String email;
@ElementCollection(fetch = FetchType.EAGER) // ✅ 별도 테이블로 저장 & 즉시 로딩
@CollectionTable(name = "user_roles", joinColumns = @JoinColumn(name = "user_id"))
@Enumerated(EnumType.STRING)
private Set<UserRole> roles = new HashSet<>();
public enum UserRole {
ROLE_USER, ROLE_ADMIN
}
}
✅ 이제 역할을 Set<UserRole> 형태로 저장 가능!
✅ User 엔티티를 조회할 때 즉시 함께 가져오므로 추가적인 쿼리 실행 없이 사용 가능!
3️⃣ 실제 데이터베이스 테이블 구조
@ElementCollection을 사용하면 JPA가 자동으로 별도의 테이블을 생성합니다.
예를 들어, User 테이블과 별도로 user_roles 테이블이 생성됩니다.
| user 테이블 (users) | |----|------| | id | email | | 1 | user1@example.com | | 2 | user2@example.com |
| user_roles 테이블 |
user_id roles
1 | ROLE_USER |
1 | ROLE_ADMIN |
2 | ROLE_USER |
✅ 이제 여러 개의 역할을 개별적으로 저장할 수 있어 검색이 쉬워지고 유지보수도 편리해집니다.
4️⃣ fetch = FetchType.EAGER 의미
📌 EAGER(즉시 로딩) 설정을 하면 User 엔티티를 가져올 때 roles도 같이 가져옴!
User user = userRepository.findById(1L).get();
System.out.println(user.getRoles()); // 🚀 자동으로 roles도 가져옴!
📌 만약 FetchType.LAZY 로 설정하면? (@ElementCollection(fetch = FetchType.LAZY))
- user.getRoles()를 호출할 때 추가 SQL 쿼리 실행됨
- 성능 최적화가 필요한 경우 LAZY를 사용할 수도 있음
📌 정리
설정 설명
@ElementCollection | 기본 엔티티가 아닌 "값 타입 컬렉션"을 저장할 때 사용 |
FetchType.EAGER | User 엔티티를 조회할 때 roles 컬렉션을 즉시 로딩 |
FetchType.LAZY | User 엔티티를 조회할 때 roles는 필요할 때만 로딩 |
🚀 즉시 로딩(FetchType.EAGER)은 작은 프로젝트나 자주 쓰이는 데이터에 적합하지만, 데이터가 많아지면 성능 문제를 초래할 수 있으므로 주의해야 합니다! 🚀
📌 @CollectionTable(name = "user_roles", joinColumns = @JoinColumn(name = "user_id")) 쉽게 설명하기
@CollectionTable은 JPA에서 @ElementCollection으로 정의된 값 타입 컬렉션을 별도의 테이블에 저장할 때 사용합니다.
즉, Set<String>이나 Set<Enum> 같은 값 타입을 엔티티와 독립적인 테이블에 저장하기 위한 설정입니다.
1️⃣ 왜 @CollectionTable이 필요한가?
만약 User 엔티티가 여러 개의 역할(Role)을 가질 수 있다면, 이를 테이블에 어떻게 저장할지 정의해야 합니다.
JPA에서 @ElementCollection을 사용하면 기본적으로 새로운 테이블이 생성되는데, 그 테이블의 이름과 매핑 방식을 설정하는 것이 바로 @CollectionTable입니다.
2️⃣ @CollectionTable 기본 예제
👀 예제 코드
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String email;
@ElementCollection(fetch = FetchType.EAGER) // ✅ 값 타입 컬렉션 저장
@CollectionTable(
name = "user_roles", // ✅ 별도의 테이블 이름 설정
joinColumns = @JoinColumn(name = "user_id") // ✅ User 테이블의 ID와 매핑
)
@Enumerated(EnumType.STRING) // ✅ Enum 값을 문자열로 저장
private Set<UserRole> roles = new HashSet<>();
public enum UserRole {
ROLE_USER, ROLE_ADMIN
}
}
✅ 주요 개념 정리
- @CollectionTable(name = "user_roles")
→ user_roles라는 별도의 테이블에 roles 저장 - @JoinColumn(name = "user_id")
→ User 테이블의 id와 연결하여 1:N 관계를 구성 - @Enumerated(EnumType.STRING)
→ Enum을 문자열 형태로 저장 (예: "ROLE_USER", "ROLE_ADMIN")
3️⃣ 실제 생성되는 데이터베이스 테이블
User 엔티티 테이블 (users)
id email
1 | user1@example.com |
2 | user2@example.com |
user_roles 값 타입 컬렉션 테이블
user_id roles
1 | ROLE_USER |
1 | ROLE_ADMIN |
2 | ROLE_USER |
✅ 이제 한 명의 유저가 여러 개의 역할을 가질 수 있으며, 별도의 테이블에서 관리되므로 검색과 유지보수가 용이합니다.
4️⃣ @CollectionTable을 사용하지 않으면?
@ElementCollection
private Set<UserRole> roles; // 🚨 테이블 이름을 설정하지 않으면 자동으로 생성됨!
📌 이 경우, JPA가 기본적으로 user_roles 테이블을 자동 생성하지만, 테이블 이름과 매핑 필드를 원하는 대로 지정할 수 없음.
📌 따라서, 실무에서는 @CollectionTable을 활용하여 테이블을 명확하게 정의하는 것이 좋습니다.
📌 결론
어노테이션 설명
@ElementCollection | 값 타입 컬렉션을 저장하는 JPA 기능 |
@CollectionTable(name = "user_roles") | 별도의 테이블(user_roles)에 저장하도록 설정 |
@JoinColumn(name = "user_id") | users 테이블의 id와 연결하여 1:N 관계 형성 |
🚀 즉, @CollectionTable은 "값 타입 컬렉션을 위한 별도 테이블을 어떻게 생성할지"를 설정하는 기능입니다! 🚀
- Total
- Today
- Yesterday
- jsp 오픈 소스
- 제품 등록
- 스프링 시큐리티(spring security)-http basic 인증
- REST API
- jstl(java standard tag library)-core
- 진수 변환
- jstl(java standard tag library)
- java web-mvc
- 특정 문자를 기준으로 자르기
- nl2br
- java-개발 환경 설정하기
- 표현 언어(expression language)
- await
- React
- 문자 자르기
- system.io
- java 키워드 정리
- 인텔리제이(intellij)
- 메이븐(maven)
- In App Purchase
- MainActor
- System.Diagnostics
- docker
- 스프링 시큐리티(spring security)
- 스프링 프레임워크(spring framewordk)
- 스프링 프레임워크(spring framework)
- java.sql
- .submit()
- 람다식(lambda expression)
- error-java
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |