Entity ์ฐ๊ด ๊ด๊ณ
์ฃผ๋ฌธ APP DB table ์ค๊ณ
๊ณ ๊ฐ(users) ํ ์ด๋ธ
| id | name |
| 1 | Robbie |
| 2 | Robbert |
create table users
(
id bigint not null auto_increment,
name varchar(255),
primary key (id)
);
์์(food) ํ ์ด๋ธ
| id | name | price |
| 1 | ํ๋ผ์ด๋ ์นํจ | 15000 |
| 2 | ์๋ ์นํจ | 20000 |
| 3 | ๊ณ ๊ตฌ๋ง ํผ์ | 30000 |
| 4 | ์๋ณด์นด๋ ํผ์ | 50000 |
create table food
(
id bigint not null auto_increment,
name varchar(255),
price float(53) not null,
primary key (id)
);
DB ํ ์ด๋ธ ๊ฐ์ ์ฐ๊ด ๊ด๊ณ
๐จ ์ฐ๊ด ๊ด๊ณ ๊ณ ๋ฏผ
[๊ณ ๊ฐ ํ ์ด๋ธ ์ ์ฅ]
ํ ๋ช ์ ๊ณ ๊ฐ์ ์์์ ์ฌ๋ฌ๊ฐ ์ฃผ๋ฌธํ ์ ์์ → ๊ณ ๊ฐ๊ณผ ์์์ 1 ๋ N ๊ด๊ณ
- ๊ณ ๊ฐ ํ ์ด๋ธ์ ์ฃผ๋ฌธํ ์์์ ์ ๋ณด๋ฅผ ํ์ ํ๊ธฐ ์ํด food_id ์ปฌ๋ผ ์ถ๊ฐ
| id | name | food_id |
| 1 | Robbie | 1 |
| 2 | Robbert | 1 |
| 3 | Robbie | 2 |
- Robbie ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ฉด ๋ถํ์ํ๊ฒ ๊ณ ๊ฐ์ ์ด๋ฆ์ด ์ค๋ณต๋๋ ๋ฌธ์ ๋ฐ์ํจ
[์์ ํ ์ด๋ธ ์ ์ฅ]
ํ๋์ ์์์ ์ฌ๋ฌ๋ช ์ ๊ณ ๊ฐ์๊ฒ ์ฃผ๋ฌธ๋ ์ ์์ → ์์๊ณผ ๊ณ ๊ฐ์ 1๋ N ๊ด๊ณ
- ์์ ํ ์ด๋ธ์ ์ฃผ๋ฌธํ ๊ณ ๊ฐ์ ์ ๋ณด๋ฅผ ํ์ ํ๊ธฐ ์ํด user_id ์ปฌ๋ผ ์ถ๊ฐ
| id | name | price | user_id |
| 1 | ํ๋ผ์ด๋ ์นํจ | 15000 | 1 |
| 2 | ํ๋ผ์ด๋ ์นํจ | 15000 | 2 |
| 3 | ์๋ ์นํจ | 20000 | 1 |
- ํ๋ผ์ด๋ ์นํจ์ ์ฌ๋ฌ ์ฌ๋์ด ์ฃผ๋ฌธํ๊ฒ ๋์์ ๋, ๋ถํ์ํ๊ฒ ์์์ ์ด๋ฆ์ด ์ค๋ณต๋๋ ๋ฌธ์ ๋ฐ์ํจ
โผ๏ธ ์ ๋ฌธ์ ํด๊ฒฐ๋ฐฉ๋ฒ โบ ์ฃผ๋ฌธ(Order) ํ ์ด๋ธ ์์ฑ
์ฃผ๋ฌธ ํ ์ด๋ธ์ ์ฃผ๋ฌธ์ ๋ํ ์ ๋ณด ๊ธฐ๋ก
create table orders
(
id bigint not null auto_increment,
user_id bigint,
food_id bigint,
order_date date,
primary key (id)
);
์ฃผ๋ฌธ ํ ์ด๋ธ์์์ ๊ณ ๊ฐ/์์ ํ ์ด๋ธ ์ธ๋ํค ์ค์
alter table orders
add constraint orders_user_fk
foreign key (user_id)
references users (id);
alter table orders
add constraint orders_food_fk
foreign key (food_id)
references food (id);
INSERT ์ํ
INSERT INTO users (name) VALUES ('Robbie');
INSERT INTO users (name) VALUES ('Robbert');
INSERT INTO food (name, price) VALUES ('ํ๋ผ์ด๋ ์นํจ', 15000);
INSERT INTO food (name, price) VALUES ('์๋
์นํจ', 20000);
INSERT INTO food (name, price) VALUES ('๊ณ ๊ตฌ๋ง ํผ์', 30000);
INSERT INTO food (name, price) VALUES ('์๋ณด์นด๋ ํผ์', 50000);
INSERT INTO orders (user_id, food_id, order_date) VALUES (1, 1, SYSDATE());
INSERT INTO orders (user_id, food_id, order_date) VALUES (2, 1, SYSDATE());
INSERT INTO orders (user_id, food_id, order_date) VALUES (2, 2, SYSDATE());
INSERT INTO orders (user_id, food_id, order_date) VALUES (1, 4, SYSDATE());
INSERT INTO orders (user_id, food_id, order_date) VALUES (2, 3, SYSDATE());

๏นก์ค๋ณต ๋ฌธ์ ํด๊ฒฐ๋จ!
- ๊ณ ๊ฐ 1๋ช ์ ์์ N๊ฐ๋ฅผ ์ฃผ๋ฌธํ ์ ์์ → ๊ณ ๊ฐ : ์์ = 1 : N ๊ด๊ณ
- ์์ 1๊ฐ๋ ๊ณ ๊ฐ N๋ช ์๊ฒ ์ฃผ๋ฌธ๋ ์ ์์ → ์์ : ๊ณ ๊ฐ = 1 : N ๊ด๊ณ
- ๊ฒฐ๋ก ์ ์ผ๋ก ๊ณ ๊ฐ๊ณผ ์์์ N : M ๊ด๊ณ์ → ๊ณ ๊ฐ : ์์ = N : M ๊ด๊ณ
๏นกN:M ๊ด๊ณ์ธ ํ ์ด๋ธ๋ค์ ์ฐ๊ด ๊ด๊ณ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์ค๊ฐ ํ ์ด๋ธ ์ฌ์ฉํ ์ ์์
ํ ์ด๋ธ ๊ฐ์ ๋ฐฉํฅ
DB ํ ์ด๋ธ๊ฐ์ ๊ด๊ณ์์ ๋ฐฉํฅ์ ํฌ๊ฒ ๋จ๋ฐฉํฅ๊ณผ ์๋ฐฉํฅ์ด ์กด์ฌํ ์ ์์
- ๋จ๋ฐฉํฅ: users ํ ์ด๋ธ์์๋ง food ํ ์ด๋ธ ์ฐธ์กฐํ ์ ์์ ๋
- ์๋ฐฉํฅ: users ํ ์ด๋ธ๊ณผ food ํ ์ด๋ธ์ด ์๋ก๋ฅผ ์ฐธ์กฐํ ์ ์์ ๋
ex) ๊ณ ๊ฐ 'Robbie'๊ฐ ์ฃผ๋ฌธํ ์์ ์ ๋ณด๋ฅผ users ํ ์ด๋ธ ๊ธฐ์ค์ผ๋ก ์กฐํ
SELECT u.name as username, f.name as foodname, o.order_date as orderdate
FROM users u
INNER JOIN orders o on u.id = o.user_id
INNER JOIN food f on o.food_id = f.id
WHERE o.user_id = 1;

ex) food ํ ์ด๋ธ ๊ธฐ์ค์ผ๋ก 'Robbie'๊ฐ ์ฃผ๋ฌธํ ์์ ์ ๋ณด ์กฐํ
SELECT u.name as username, f.name as foodname, o.order_date as orderdate
FROM food f
INNER JOIN orders o on f.id = o.food_id
INNER JOIN users u on o.user_id = u.id
WHERE o.user_id = 1;

์ ๋ ๊ฒฐ๊ณผ๋ ๋์ผํจ! ์ฆ, DB์์๋ ์ด๋ค ํ ์ด๋ธ์ ๊ธฐ์ค์ผ๋ก ํ๋ ์ํ๋ ์ ๋ณด๋ฅผ JOIN์ ์ฌ์ฉํด์ ์กฐํํ ์ ์์!
๋ฐ๋ผ์, DB์์๋ ํ ์ด๋ธ ์ฌ์ด์ ์ฐ๊ด ๊ด๊ณ๋ฅผ FK(์ธ๋ ํค)๋ก ๋งบ์ ์ ์๊ณ , ๋ฐฉํฅ ์๊ด์์ด ์กฐํ๊ฐ ๊ฐ๋ฅ(๋ฐฉํฅ ๊ฐ๋ X)
Entity ๊ฐ์ ์ฐ๊ด ๊ด๊ณ
JPA Entity์์์ ํ ์ด๋ธ๊ฐ์ ์ฐ๊ด๊ด๊ณ ํํ ๋ฐฉ์
[์์ : ๊ณ ๊ฐ = N : 1 ๊ด๊ณ ํํ]
// ์์ ํ
์ด๋ธ
@Entity
@Table(name = "food")
public class Food {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private double price;
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
}
// ๊ณ ๊ฐ ํ
์ด๋ธ
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy = "user")
private List<Food> foodList = new ArrayList<>();
}
- ํ ๋ช ์ ๊ณ ๊ฐ์ ์ฌ๋ฌ๋ฒ ์ฃผ๋ฌธ์ด ๊ฐ๋ฅํ ์ํฉ์ผ๋ก, ์ด๋ฅผ Entity์์ ์ฌ๋ฌ๋ฒ ๊ฐ๋ฅํจ์ ํํํ๊ธฐ ์ํด Java ์ปฌ๋ ์ ์ ์ฌ์ฉํด List ํ์์ผ๋ก ํํ
- DB ํ
์ด๋ธ์์๋ ๊ณ ๊ฐ ํ
์ด๋ธ ๊ธฐ์ค์ผ๋ก ์์์ ์ ๋ณด๋ฅผ ์กฐํํ๋ ค๊ณ ํ ๋ JOIN์ ์ฌ์ฉํด ๋ฐ๋ก ์กฐํ๊ฐ ๊ฐ๋ฅํ์ง๋ง,
๊ณ ๊ฐ Entity ์ ์ฅ์์๋ ์์ Entity ์ ๋ณด๋ฅผ ๊ฐ์ง๊ณ ์์ง ์์ผ๋ฉด ์์์ ์ ๋ณด๋ฅผ ์กฐํํ ๋ฐฉ๋ฒ์ด ์์! - ๋ฐ๋ผ์ DB ํ ์ด๋ธ์ ์ค์ ์ปฌ๋ผ์ผ๋ก ์กด์ฌํ์ง ์์ง๋ง Entity ์ํ์์ ๋ค๋ฅธ Entity๋ฅผ ์ฐธ์กฐํ๊ธฐ ์ํด ์์ ๊ฐ์ ๋ฐฉ๋ฒ ์ฌ์ฉ
- ํ์ฌ ์์ Entity์ ๊ณ ๊ฐ Entity๋ ์๋ก๋ฅผ ์ฐธ์กฐํ๊ณ ์๊ธฐ ๋๋ฌธ์, ์ด๋ฌํ ๊ด๊ณ๋ฅผ ์๋ฐฉํฅ ๊ด๊ณ๋ผ๊ณ ๋ถ๋ฆ
[๋จ๋ฐฉํฅ ๊ด๊ณ]
// ์์ ํ
์ด๋ธ
@Entity
@Table(name = "food")
public class Food {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private double price;
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
}
// ๊ณ ๊ฐ ํ
์ด๋ธ
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
- ์์ Entity์์๋ง ๊ณ ๊ฐ Entity ์ฐธ์กฐํ ์ ์์
- ๊ณ ๊ฐ Entity์๋ ์์ Entity์ ์ ๋ณด๊ฐ ์๊ธฐ ๋๋ฌธ์ ์์ ์ ๋ณด๋ฅผ ์กฐํํ ์ ์์
์ฆ, Entity์์๋ ์๋ Entity๋ฅผ ์ฐธ์กฐํด Entity ์ฌ์ด์ ์ฐ๊ด๊ด๊ณ๋ฅผ ๋งบ์ ์ ์์! ๋ฐ๋ผ์ Entity์์๋ DB ํ ์ด๋ธ์๋ ์๋ ๋ฐฉํฅ์ ๊ฐ๋ ์ด ์กด์ฌํจ
1 ๋ 1 ๊ด๊ณ
@OneToOne ์ด๋ ธํ ์ด์ ์ 1๋ 1 ๊ด๊ณ๋ฅผ ๋งบ์ด์ฃผ๋ ์ญํ ์ํ
ex) ๊ณ ๊ฐ Entity์ ์์ Entity๊ฐ 1๋ 1 ๊ด๊ณ๋ผ ๊ฐ์ ํ๊ณ ๊ด๊ณ ๋งบ์ด๋ณด๊ธฐ
๋จ๋ฐฉํฅ ๊ด๊ณ
์ธ๋ ํค ์ฃผ์ธ ์ ํ๊ธฐ
- Entity์์ ์ธ๋ ํค์ ์ฃผ์ธ์ ์ผ๋ฐ์ ์ผ๋ก N(๋ค)์ ๊ด๊ณ์ธ Entity ์ด์ง๋ง, 1๋ 1 ๊ด๊ณ์์๋ ์ธ๋ ํค์ ์ฃผ์ธ์ ์ง์ ์ง์ ํด์ผํจ
- ์ธ๋ ํค ์ฃผ์ธ๋ง์ด ์ธ๋ ํค๋ฅผ ๋ฑ๋ก, ์์ , ์ญ์ ํ ์ ์์ผ๋ฉฐ, ์ฃผ์ธ์ด ์๋ ์ชฝ์ ์ค์ง ์ธ๋ ํค๋ฅผ ์ฝ๊ธฐ๋ง ๊ฐ๋ฅ!
- @JoinColumn()์ ์ธ๋ ํค์ ์ฃผ์ธ์ด ํ์ฉํ๋ ์ ๋ํ ์ด์ ์ผ๋ก, ์ปฌ๋ผ๋ช , null ์ฌ๋ถ, unique ์ฌ๋ถ ๋ฑ ์ง์ ๊ฐ๋ฅ
1) ์์ Entity๊ฐ ์ธ๋ ํค ์ฃผ์ธ์ธ ๊ฒฝ์ฐ

package com.sparta.jpaadvance.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
@Entity
@Getter
@Setter
@Table(name = "food")
public class Food {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private double price;
@OneToOne
@JoinColumn(name = "user_id")
private User user;
}
package com.sparta.jpaadvance.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
@Entity
@Getter
@Setter
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
2) ๊ณ ๊ฐ Entity๊ฐ ์ธ๋ ํค ์ฃผ์ธ์ธ ๊ฒฝ์ฐ

๋จ๋ฐฉํฅ ๊ด๊ณ ํ ์คํธ
package com.sparta.jpaadvance.relation;
import com.sparta.jpaadvance.entity.Food;
import com.sparta.jpaadvance.entity.User;
import com.sparta.jpaadvance.repository.FoodRepository;
import com.sparta.jpaadvance.repository.UserRepository;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.transaction.annotation.Transactional;
@Transactional
@SpringBootTest
public class OneToOneTest {
@Autowired
FoodRepository foodRepository;
@Autowired
UserRepository userRepository;
@Test
@Rollback(value = false) // ํ
์คํธ์์๋ @Transactional ์ ์ํด ์๋ rollback ๋จ์ผ๋ก false ์ค์ ํด์ค๋ค.
@DisplayName("1๋1 ๋จ๋ฐฉํฅ ํ
์คํธ")
void test1() {
User user = new User();
user.setName("Robbie");
// ์ธ๋ ํค์ ์ฃผ์ธ์ธ Food Entity user ํ๋์ user ๊ฐ์ฒด๋ฅผ ์ถ๊ฐํด ์ค๋๋ค.
Food food = new Food();
food.setName("ํ๋ผ์ด๋ ์นํจ");
food.setPrice(15000);
food.setUser(user); // ์ธ๋ ํค(์ฐ๊ด ๊ด๊ณ) ์ค์
userRepository.save(user);
foodRepository.save(food);
}
}

์๋ฐฉํฅ ๊ด๊ณ
- ์๋ฐฉํฅ ๊ด๊ณ์์ ์ธ๋ ํค์ ์ฃผ์ธ์ ์ง์ ํด ์ค ๋ mappedBy ์ต์
์ฌ์ฉํจ
- mappedBy์ ์์ฑ๊ฐ์ ์ธ๋ ํค์ ์ฃผ์ธ์ธ ์๋ Entity์ ํ๋๋ช ์ ์๋ฏธ - ์ธ๋ ํค์ ์ฃผ์ธ์ ์๋ Entity ํ์ ์ ํ๋๋ฅผ ๊ฐ์ง๋ฉด์ @JoinColumn()์ ํ์ฉํด ์ธ๋ ํค์ ์์ฑ ์ค์
- ์๋ Entity๋ ์ธ๋ ํค์ ์ฃผ์ธ Entity ํ์ ์ ํ๋๋ฅผ ๊ฐ์ง๋ฉด์ mappedBy ์ต์ ์ ์ฌ์ฉํด ์์ฑ ๊ฐ์ผ๋ก ์ธ๋ ํค์ ์ฃผ์ธ Entity์ ์ ์ธ๋ @JoinColumn()์ผ๋ก ์ค์ ๋๊ณ ์๋ ํ๋๋ช ๋ฃ์ด์ฃผ๋ฉด๋จ!
1) ์์ Entity๊ฐ ์ธ๋ ํค ์ฃผ์ธ์ธ ๊ฒฝ์ฐ

package com.sparta.jpaadvance.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
@Entity
@Getter
@Setter
@Table(name = "food")
public class Food {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private double price;
@OneToOne
@JoinColumn(name = "user_id")
private User user;
}
package com.sparta.jpaadvance.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
@Entity
@Getter
@Setter
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToOne(mappedBy = "user")
private Food food;
public void addFood(Food food) {
this.food = food;
food.setUser(this);
}
}
2) ๊ณ ๊ฐ Entity๊ฐ ์ธ๋ ํค ์ฃผ์ธ์ธ ๊ฒฝ์ฐ

์๋ฐฉํฅ ๊ด๊ณ ํ ์คํธ 1
@Test
@Rollback(value = false)
@DisplayName("1๋1 ์๋ฐฉํฅ ํ
์คํธ : ์ธ๋ ํค ์ ์ฅ ์คํจ")
void test2() {
Food food = new Food();
food.setName("๊ณ ๊ตฌ๋ง ํผ์");
food.setPrice(30000);
// ์ธ๋ ํค์ ์ฃผ์ธ์ด ์๋ User ์์ Food ๋ฅผ ์ ์ฅํด๋ณด๊ฒ ์ต๋๋ค.
User user = new User();
user.setName("Robbie");
user.setFood(food);
userRepository.save(user);
foodRepository.save(food);
// ํ์ธํด ๋ณด์๋ฉด user_id ๊ฐ์ด ๋ค์ด๊ฐ ์์ง ์์ ๊ฒ์ ํ์ธํ์ค ์ ์์ต๋๋ค.
}

โบ ์ธ๋ ํค์ ์ฃผ์ธ๋ง์ด ์ธ๋ ํค๋ฅผ ์ปจํธ๋กคํ ์ ์์!
์๋ฐฉํฅ ๊ด๊ณ ํ ์คํธ 2
@Test
@Rollback(value = false)
@DisplayName("1๋1 ์๋ฐฉํฅ ํ
์คํธ : ์ธ๋ ํค ์ ์ฅ ์คํจ -> ์ฑ๊ณต")
void test3() {
Food food = new Food();
food.setName("๊ณ ๊ตฌ๋ง ํผ์");
food.setPrice(30000);
// ์ธ๋ ํค์ ์ฃผ์ธ์ด ์๋ User ์์ Food ๋ฅผ ์ ์ฅํ๊ธฐ ์ํด addFood() ๋ฉ์๋ ์ถ๊ฐ
// ์ธ๋ ํค(์ฐ๊ด ๊ด๊ณ) ์ค์ food.setUser(this); ์ถ๊ฐ
User user = new User();
user.setName("Robbie");
user.addFood(food);
userRepository.save(user);
foodRepository.save(food);
}

โบ ์ธ๋ ํค์ ์ฃผ์ธ๋ง์ด ์ธ๋ ํค๋ฅผ ์ปจํธ๋กคํ ์ ์์!
์๋ฐฉํฅ ๊ด๊ณ ํ ์คํธ 3
@Test
@Rollback(value = false)
@DisplayName("1๋1 ์๋ฐฉํฅ ํ
์คํธ")
void test4() {
User user = new User();
user.setName("Robbert");
Food food = new Food();
food.setName("๊ณ ๊ตฌ๋ง ํผ์");
food.setPrice(30000);
food.setUser(user); // ์ธ๋ ํค(์ฐ๊ด ๊ด๊ณ) ์ค์
userRepository.save(user);
foodRepository.save(food);
}
โ ๏ธ ์ฃผ์
1. ์ธ๋ ํค์ ์ฃผ์ธ Entity์์ @JoinColumn() ์ด๋ ธํ ์ด์ ์ ์ฌ์ฉํ์ง ์์๋ default ์ต์ ์ด ์ ์ฉ๋๊ธฐ ๋๋ฌธ์ ์๋ต ๊ฐ๋ฅํจ!
๋ค๋ง, 1๋ N ๊ด๊ณ์์ ์ธ๋ ํค์ ์ฃผ์ธ Entity๊ฐ @JoinColumn() ์ด๋ ธํ ์ด์ ์ ์๋ตํ๋ค๋ฉด, JPA๊ฐ ์ธ๋ํค๋ฅผ ์ ์ฅํ ์ปฌ๋ผ์ ํ์ ํ ์ ์์ด์ ์๋ํ์ง ์์ ์ค๊ฐ ํ ์ด๋ธ ์์ฑ๋จ
2. ์๋ฐฉํฅ ๊ด๊ณ์์ mappedBy ์ต์ ์ ์๋ตํ ๊ฒฝ์ฐ JPA๊ฐ ์ธ๋ ํค์ ์ฃผ์ธ Entity๋ฅผ ํ์ ํ ์ ์์ด ์๋ํ์ง ์์ ์ค๊ฐ ํ ์ด๋ธ ์์ฑ๋๊ธฐ ๋๋ฌธ์ ๋ฐ๋์ ์ค์ ํด์ฃผ๋๊ฒ ์ข์!
N๋ 1 ๊ด๊ณ
@ManyToOne ์ด๋ ธํ ์ด์ ์ N ๋ 1 ๊ด๊ณ๋ฅผ ๋งบ์ด์ฃผ๋ ์ญํ ์ ํจ
ex) ์์ Entity์ ๊ณ ๊ฐ Entity๊ฐ N ๋ 1 ๊ด๊ณ๋ผ ๊ฐ์ ํ๊ณ ๊ด๊ณ๋ฅผ ๋งบ์ด๋ณด๊ธฐ
๋จ๋ฐฉํฅ ๊ด๊ณ
- ์์ Entity๊ฐ N์ ๊ด๊ณ๋ก ์ธ๋ ํค์ ์ฃผ์ธ์ธ ๊ฒฝ์ฐ

package com.sparta.jpaadvance.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
@Entity
@Getter
@Setter
@Table(name = "food")
public class Food {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private double price;
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
}
package com.sparta.jpaadvance.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
@Entity
@Getter
@Setter
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
๋จ๋ฐฉํฅ ๊ด๊ณ ํ ์คํธ
@Test
@Rollback(value = false)
@DisplayName("N๋1 ๋จ๋ฐฉํฅ ํ
์คํธ")
void test1() {
User user = new User();
user.setName("Robbie");
Food food = new Food();
food.setName("ํ๋ผ์ด๋ ์นํจ");
food.setPrice(15000);
food.setUser(user); // ์ธ๋ ํค(์ฐ๊ด ๊ด๊ณ) ์ค์
Food food2 = new Food();
food2.setName("์๋
์นํจ");
food2.setPrice(20000);
food2.setUser(user); // ์ธ๋ ํค(์ฐ๊ด ๊ด๊ณ) ์ค์
userRepository.save(user);
foodRepository.save(food);
foodRepository.save(food2);
}

์๋ฐฉํฅ ๊ด๊ณ
- ์๋ฐฉํฅ ์ฐธ์กฐ๋ฅผ ์ํด ๊ณ ๊ฐ Entity์์ Java ์ปฌ๋ ์ ์ ์ฌ์ฉํด ์์ Entity ์ฐธ์กฐ

package com.sparta.jpaadvance.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
@Entity
@Getter
@Setter
@Table(name = "food")
public class Food {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private double price;
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
}
package com.sparta.jpaadvance.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.List;
@Entity
@Getter
@Setter
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy = "user")
private List<Food> foodList = new ArrayList<>();
public void addFoodList(Food food) {
this.foodList.add(food);
food.setUser(this); // ์ธ๋ ํค(์ฐ๊ด ๊ด๊ณ) ์ค์
}
}
์๋ฐฉํฅ ๊ด๊ณ ํ ์คํธ 1
@Test
@Rollback(value = false)
@DisplayName("N๋1 ์๋ฐฉํฅ ํ
์คํธ : ์ธ๋ ํค ์ ์ฅ ์คํจ")
void test2() {
Food food = new Food();
food.setName("ํ๋ผ์ด๋ ์นํจ");
food.setPrice(15000);
Food food2 = new Food();
food2.setName("์๋
์นํจ");
food2.setPrice(20000);
// ์ธ๋ ํค์ ์ฃผ์ธ์ด ์๋ User ์์ Food ๋ฅผ ์ ์ฅํด๋ณด๊ฒ ์ต๋๋ค.
User user = new User();
user.setName("Robbie");
user.getFoodList().add(food);
user.getFoodList().add(food2);
userRepository.save(user);
foodRepository.save(food);
foodRepository.save(food2);
// ํ์ธํด ๋ณด์๋ฉด user_id ๊ฐ์ด ๋ค์ด๊ฐ ์์ง ์์ ๊ฒ์ ํ์ธํ์ค ์ ์์ต๋๋ค.
}

์๋ฐฉํฅ ๊ด๊ณ ํ ์คํธ 2
@Test
@Rollback(value = false)
@DisplayName("N๋1 ์๋ฐฉํฅ ํ
์คํธ : ์ธ๋ ํค ์ ์ฅ ์คํจ -> ์ฑ๊ณต")
void test3() {
Food food = new Food();
food.setName("ํ๋ผ์ด๋ ์นํจ");
food.setPrice(15000);
Food food2 = new Food();
food2.setName("์๋
์นํจ");
food2.setPrice(20000);
// ์ธ๋ ํค์ ์ฃผ์ธ์ด ์๋ User ์์ Food ๋ฅผ ์ฝ๊ฒ ์ ์ฅํ๊ธฐ ์ํด addFoodList() ๋ฉ์๋ ์์ฑํ๊ณ
// ํด๋น ๋ฉ์๋์ ์ธ๋ ํค(์ฐ๊ด ๊ด๊ณ) ์ค์ food.setUser(this); ์ถ๊ฐ
User user = new User();
user.setName("Robbie");
user.addFoodList(food);
user.addFoodList(food2);
userRepository.save(user);
foodRepository.save(food);
foodRepository.save(food2);
}

์๋ฐฉํฅ ๊ด๊ณ ํ ์คํธ 3
@Test
@Rollback(value = false)
@DisplayName("N๋1 ์๋ฐฉํฅ ํ
์คํธ")
void test4() {
User user = new User();
user.setName("Robbert");
Food food = new Food();
food.setName("๊ณ ๊ตฌ๋ง ํผ์");
food.setPrice(30000);
food.setUser(user); // ์ธ๋ ํค(์ฐ๊ด ๊ด๊ณ) ์ค์
Food food2 = new Food();
food2.setName("์๋ณด์นด๋ ํผ์");
food2.setPrice(50000);
food2.setUser(user); // ์ธ๋ ํค(์ฐ๊ด ๊ด๊ณ) ์ค์
userRepository.save(user);
foodRepository.save(food);
foodRepository.save(food2);
}

1๋ N ๊ด๊ณ
@OneToMany ์ด๋ ธํ ์ด์ ์ 1 ๋ ๋ค ๊ด๊ณ๋ฅผ ๋งบ์ด์ฃผ๋ ์ญํ ์ ํจ
ex) ์์ Entity์ ๊ณ ๊ฐ Entity๊ฐ 1 ๋ ๋ค ๊ด๊ณ๋ผ ๊ฐ์ ํ๊ณ ๊ด๊ณ๋ฅผ ๋งบ์ด๋ณด๊ธฐ
๋จ๋ฐฉํฅ ๊ด๊ณ
- ์ธ๋ ํค๋ฅผ ๊ด๋ฆฌํ๋ ์ฃผ์ธ์ ์์ Entity์ด์ง๋ง ์ค์ ์ธ๋ ํค๋ ๊ณ ๊ฐ Entity๊ฐ ๊ฐ์ง๊ณ ์์
→ 1 : N์์ N ๊ด๊ณ์ ํ ์ด๋ธ์ด ์ธ๋ ํค๋ฅผ ๊ฐ์ง ์ ์๊ธฐ ๋๋ฌธ์ ์ธ๋ ํค๋ N ๊ด๊ณ์ธ users ํ ์ด๋ธ์ ์ธ๋ ํค ์ปฌ๋ผ์ ๋ง๋ค์ด ์ถ๊ฐํ์ง๋ง ์ธ๋ ํค์ ์ฃผ์ธ์ธ ์์ Entity๋ฅผ ํตํด ๊ด๋ฆฌํจ

- ์ธ๋ ํค๋ฅผ ์์ Entity๊ฐ ์ง์ ๊ฐ์ง ์ ์๋ค๋ฉด INSERT ๋ฐ์ ์ ํ๋ฒ์ ์ฒ๋ฆฌํ ์ ์์ง๋ง ์ค์ DB์์ ์ธ๋ ํค๋ฅผ ๊ณ ๊ฐ ํ ์ด๋ธ์ด ๊ฐ์ง๊ณ ์๊ธฐ ๋๋ฌธ์ ์ถ๊ฐ์ ์ธ UPDATE๊ฐ ๋ฐ์ํ๋ค๋ ๋จ์ ์ด ์กด์ฌํจ
package com.sparta.jpaadvance.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.List;
@Entity
@Getter
@Setter
@Table(name = "food")
public class Food {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private double price;
@OneToMany
@JoinColumn(name = "food_id") // users ํ
์ด๋ธ์ food_id ์ปฌ๋ผ
private List<User> userList = new ArrayList<>();
}
package com.sparta.jpaadvance.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
@Entity
@Getter
@Setter
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
๋จ๋ฐฉํฅ ๊ด๊ณ ํ ์คํธ
@Test
@Rollback(value = false)
@DisplayName("1๋N ๋จ๋ฐฉํฅ ํ
์คํธ")
void test1() {
User user = new User();
user.setName("Robbie");
User user2 = new User();
user2.setName("Robbert");
Food food = new Food();
food.setName("ํ๋ผ์ด๋ ์นํจ");
food.setPrice(15000);
food.getUserList().add(user); // ์ธ๋ ํค(์ฐ๊ด ๊ด๊ณ) ์ค์
food.getUserList().add(user2); // ์ธ๋ ํค(์ฐ๊ด ๊ด๊ณ) ์ค์
userRepository.save(user);
userRepository.save(user2);
foodRepository.save(food);
// ์ถ๊ฐ์ ์ธ UPDATE ์ฟผ๋ฆฌ ๋ฐ์์ ํ์ธํ ์ ์์ต๋๋ค.
}

์๋ฐฉํฅ ๊ด๊ณ
- 1๋ N ๊ด๊ณ์์๋ ์ผ๋ฐ์ ์ผ๋ก ์๋ฐฉํฅ ๊ด๊ณ๊ฐ ์กด์ฌํ์ง ์์
- 1๋ N ๊ด๊ณ์์ ์๋ฐฉํฅ ๊ด๊ณ๋ฅผ ๋งบ์ผ๋ ค๋ฉด ์์ Entity๋ฅผ ์ธ๋ ํค์ ์ฃผ์ธ์ผ๋ก ์ ํด์ฃผ๊ธฐ ์ํด ๊ณ ๊ฐ Entity์์ mappedBy ์ต์ ์ ์ฌ์ฉํด์ผ ํ์ง๋ง @ManyToOne ์ด๋ ธํ ์ด์ ์ mappedBy ์์ฑ์ ์ ๊ณตํ์ง ์์
- N ๊ด๊ณ์ Entity์ธ ๊ณ ๊ฐ Entity์์ @JoinColumn์ insertable๊ณผ updatable ์ต์ ์ false๋ก ์ค์ ํด ์์ชฝ์ผ๋ก JOIN ์ค์ ์ ํ๋ฉด ์๋ฐฉํฅ์ฒ๋ผ ์ค์ ํ ์ ์์ง๋ง, ์ถ์ฒํ์ง๋ ์์!
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@ManyToOne
@JoinColumn(name = "food_id", insertable = false, updatable = false)
private Food food;
}
N๋ M ๊ด๊ณ
@ManyToMany ์ด๋ ธํ ์ด์ ์ N ๋ M ๊ด๊ณ๋ฅผ ๋งบ์ด์ฃผ๋ ์ญํ ์ ํจ
ex) ์์ Entity์ ๊ณ ๊ฐ Entity๊ฐ N ๋ M ๊ด๊ณ๋ผ ๊ฐ์ ํ๊ณ ๊ด๊ณ๋ฅผ ๋งบ์ด๋ณด๊ธฐ
N๋ M๊ด๊ณ๋ฅผ ์ํด ์ค๊ฐ ํ ์ด๋ธ ์์ฑํด์ ์ฌ์ฉํจ
๋จ๋ฐฉํฅ ๊ด๊ณ
- ์์ Entity๊ฐ ์ธ๋ ํค์ ์ฃผ์ธ์ธ ๊ฒฝ์ฐ

package com.sparta.jpaadvance.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.List;
@Entity
@Getter
@Setter
@Table(name = "food")
public class Food {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private double price;
@ManyToMany
@JoinTable(name = "orders", // ์ค๊ฐ ํ
์ด๋ธ ์์ฑ
joinColumns = @JoinColumn(name = "food_id"), // ํ์ฌ ์์น์ธ Food Entity ์์ ์ค๊ฐ ํ
์ด๋ธ๋ก ์กฐ์ธํ ์ปฌ๋ผ ์ค์
inverseJoinColumns = @JoinColumn(name = "user_id")) // ๋ฐ๋ ์์น์ธ User Entity ์์ ์ค๊ฐ ํ
์ด๋ธ๋ก ์กฐ์ธํ ์ปฌ๋ผ ์ค์
private List<User> userList = new ArrayList<>();
}
package com.sparta.jpaadvance.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
@Entity
@Getter
@Setter
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
- ์์ฑ๋๋ ์ค๊ฐ ํ ์ด๋ธ์ PK๊ฐ ์กด์ฌํ์ง ์์. ์ฆ, ์์ฑ๋๋ ์ค๊ฐ ํ ์ด๋ธ์ ์ปจํธ๋กคํ๊ธฐ ์ด๋ ต๊ธฐ ๋๋ฌธ์ ์ถํ์ ์ค๊ฐ ํ ์ด๋ธ์ ๋ณ๊ฒฝ์ด ๋ฐ์ํ ๊ฒฝ์ฐ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ๊ฐ๋ฅ์ฑ์ด ์์
๋จ๋ฐฉํฅ ๊ด๊ณ ํ ์คํธ
@Test
@Rollback(value = false)
@DisplayName("N๋M ๋จ๋ฐฉํฅ ํ
์คํธ")
void test1() {
User user = new User();
user.setName("Robbie");
User user2 = new User();
user2.setName("Robbert");
Food food = new Food();
food.setName("ํ๋ผ์ด๋ ์นํจ");
food.setPrice(15000);
food.getUserList().add(user);
food.getUserList().add(user2);
userRepository.save(user);
userRepository.save(user2);
foodRepository.save(food);
// ์๋์ผ๋ก ์ค๊ฐ ํ
์ด๋ธ orders ๊ฐ create ๋๊ณ insert ๋จ์ ํ์ธํ ์ ์์ต๋๋ค.
}


์๋ฐฉํฅ ๊ด๊ณ
- ์์ Entity๊ฐ ์ธ๋ ํค์ ์ฃผ์ธ์ธ ๊ฒฝ์ฐ

package com.sparta.jpaadvance.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.List;
@Entity
@Getter
@Setter
@Table(name = "food")
public class Food {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private double price;
@ManyToMany
@JoinTable(name = "orders", // ์ค๊ฐ ํ
์ด๋ธ ์์ฑ
joinColumns = @JoinColumn(name = "food_id"), // ํ์ฌ ์์น์ธ Food Entity ์์ ์ค๊ฐ ํ
์ด๋ธ๋ก ์กฐ์ธํ ์ปฌ๋ผ ์ค์
inverseJoinColumns = @JoinColumn(name = "user_id")) // ๋ฐ๋ ์์น์ธ User Entity ์์ ์ค๊ฐ ํ
์ด๋ธ๋ก ์กฐ์ธํ ์ปฌ๋ผ ์ค์
private List<User> userList = new ArrayList<>();
}
package com.sparta.jpaadvance.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.List;
@Entity
@Getter
@Setter
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@ManyToMany(mappedBy = "userList")
private List<Food> foodList = new ArrayList<>();
}
- ๋ฐ๋ ๋ฐฉํฅ์ธ ๊ณ ๊ฐ Entity์ @ManyToMany๋ก ์์ Entity๋ก ์ฐ๊ฒฐํ๊ณ mappedBy ์ต์ ์ ์ค์ ํด ์ธ๋ ํค์ ์ฃผ์ธ์ ์ค์ ํ๋ฉด ์๋ฐฉํฅ ๊ด๊ณ ๋งบ์์ด ๊ฐ๋ฅํจ
์๋ฐฉํฅ ๊ด๊ณ ํ ์คํธ 1
@Test
@Rollback(value = false)
@DisplayName("N๋M ์๋ฐฉํฅ ํ
์คํธ : ์ธ๋ ํค ์ ์ฅ ์คํจ")
void test2() {
Food food = new Food();
food.setName("ํ๋ผ์ด๋ ์นํจ");
food.setPrice(15000);
Food food2 = new Food();
food2.setName("์๋
์นํจ");
food2.setPrice(20000);
// ์ธ๋ ํค์ ์ฃผ์ธ์ด ์๋ User ์์ Food ๋ฅผ ์ ์ฅํด๋ณด๊ฒ ์ต๋๋ค.
User user = new User();
user.setName("Robbie");
user.getFoodList().add(food);
user.getFoodList().add(food2);
userRepository.save(user);
foodRepository.save(food);
foodRepository.save(food2);
// ํ์ธํด ๋ณด์๋ฉด orders ํ
์ด๋ธ์ food_id, user_id ๊ฐ์ด ๋ค์ด๊ฐ ์์ง ์์ ๊ฒ์ ํ์ธํ์ค ์ ์์ต๋๋ค.
}

์๋ฐฉํฅ ๊ด๊ณ ํ ์คํธ 2
@Test
@Rollback(value = false)
@DisplayName("N๋M ์๋ฐฉํฅ ํ
์คํธ : ์ธ๋ ํค ์ ์ฅ ์คํจ -> ์ฑ๊ณต")
void test3() {
Food food = new Food();
food.setName("ํ๋ผ์ด๋ ์นํจ");
food.setPrice(15000);
Food food2 = new Food();
food2.setName("์๋
์นํจ");
food2.setPrice(20000);
// ์ธ๋ ํค์ ์ฃผ์ธ์ด ์๋ User ์์ Food ๋ฅผ ์ฝ๊ฒ ์ ์ฅํ๊ธฐ ์ํด addFoodList() ๋ฉ์๋๋ฅผ ์์ฑํด์ ์ฌ์ฉํฉ๋๋ค.
// ์ธ๋ ํค(์ฐ๊ด ๊ด๊ณ) ์ค์ ์ ์ํด Food ์์ userList ๋ฅผ ํธ์ถํด user ๊ฐ์ฒด ์์ ์ add ํฉ๋๋ค.
User user = new User();
user.setName("Robbie");
user.addFoodList(food);
user.addFoodList(food2);
userRepository.save(user);
foodRepository.save(food);
foodRepository.save(food2);
}

์๋ฐฉํฅ ๊ด๊ณ ํ ์คํธ 3
@Test
@Rollback(value = false)
@DisplayName("N๋M ์๋ฐฉํฅ ํ
์คํธ")
void test4() {
User user = new User();
user.setName("Robbie");
User user2 = new User();
user2.setName("Robbert");
Food food = new Food();
food.setName("์๋ณด์นด๋ ํผ์");
food.setPrice(50000);
food.getUserList().add(user); // ์ธ๋ ํค(์ฐ๊ด ๊ด๊ณ) ์ค์
food.getUserList().add(user2); // ์ธ๋ ํค(์ฐ๊ด ๊ด๊ณ) ์ค์
Food food2 = new Food();
food2.setName("๊ณ ๊ตฌ๋ง ํผ์");
food2.setPrice(30000);
food2.getUserList().add(user); // ์ธ๋ ํค(์ฐ๊ด ๊ด๊ณ) ์ค์
userRepository.save(user);
userRepository.save(user2);
foodRepository.save(food);
foodRepository.save(food2);
// User ๋ฅผ ํตํด food ์ ์ ๋ณด ์กฐํ
System.out.println("user.getName() = " + user.getName());
List<Food> foodList = user.getFoodList();
for (Food f : foodList) {
System.out.println("f.getName() = " + f.getName());
System.out.println("f.getPrice() = " + f.getPrice());
}
// ์ธ๋ ํค์ ์ฃผ์ธ์ด ์๋ User ๊ฐ์ฒด์ Food ์ ์ ๋ณด๋ฅผ ๋ฃ์ด์ฃผ์ง ์์๋ DB ์ ์ฅ์๋ ๋ฌธ์ ๊ฐ ์์ง๋ง
// ์ด์ฒ๋ผ User ๋ฅผ ์ฌ์ฉํ์ฌ food ์ ์ ๋ณด๋ฅผ ์กฐํํ ์๋ ์์ต๋๋ค.
}

- ์ธ๋ ํค์ ์ฃผ์ธ์ด ์๋ User ๊ฐ์ฒด์ Food ์ ๋ณด๋ฅผ ๋ฃ์ด์ฃผ์ง ์์๊ธฐ ๋๋ฌธ์ ์ถ๋ ฅ๋์ง ์์
- ์ฆ ์๋ฐฉํฅ ๊ด๊ณ์ผ ๋, ์ธ๋ ํค์ ์ฃผ์ธ์ด ์๋ ์ชฝ์ ๋ฐ์ดํฐ๋ฅผ ๋ฃ์ด์ฃผ์ง ์์ผ๋ฉด ๋ก์ง ์ํ X
์๋ฐฉํฅ ๊ด๊ณ ํ ์คํธ 4
@Test
@Rollback(value = false)
@DisplayName("N๋M ์๋ฐฉํฅ ํ
์คํธ : ๊ฐ์ฒด์ ์๋ฐฉํฅ์ ์ฅ์ ํ์ฉ")
void test5() {
User user = new User();
user.setName("Robbie");
User user2 = new User();
user2.setName("Robbert");
// addUserList() ๋ฉ์๋๋ฅผ ์์ฑํด user ์ ๋ณด๋ฅผ ์ถ๊ฐํ๊ณ
// ํด๋น ๋ฉ์๋์ ๊ฐ์ฒด ํ์ฉ์ ์ํด user ๊ฐ์ฒด์ food ์ ๋ณด๋ฅผ ์ถ๊ฐํ๋ ์ฝ๋๋ฅผ ์ถ๊ฐํฉ๋๋ค. user.getFoodList().add(this);
Food food = new Food();
food.setName("์๋ณด์นด๋ ํผ์");
food.setPrice(50000);
food.addUserList(user);
food.addUserList(user2);
Food food2 = new Food();
food2.setName("๊ณ ๊ตฌ๋ง ํผ์");
food2.setPrice(30000);
food2.addUserList(user);
userRepository.save(user);
userRepository.save(user2);
foodRepository.save(food);
foodRepository.save(food2);
// User ๋ฅผ ํตํด food ์ ์ ๋ณด ์กฐํ
System.out.println("user.getName() = " + user.getName());
List<Food> foodList = user.getFoodList();
for (Food f : foodList) {
System.out.println("f.getName() = " + f.getName());
System.out.println("f.getPrice() = " + f.getPrice());
}
}

์ค๊ฐ ํ ์ด๋ธ ๋ง๋ค๊ธฐ
์์ ์ค๊ฐ ํ ์ด๋ธ์ ์ปจํธ๋กคํ๊ธฐ ํ๋ค๊ธฐ ๋๋ฌธ์, ์ง์ ์ค๊ฐ ํ ์ด๋ธ์ ์์ฑํด์ ์ฌ์ฉํด ๋ฌธ์ ํด๊ฒฐํ๊ธฐ
→ ์ธ๋ ํค์ ์ฃผ์ธ์ด Order Entity๊ฐ ๋จ!

Order Entity(์ค๊ฐ ํ ์ด๋ธ)
package com.sparta.jpaadvance.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
@Entity
@Getter
@Setter
@Table(name = "orders")
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
@JoinColumn(name = "food_id")
private Food food;
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
}
Food Entity
package com.sparta.jpaadvance.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.List;
@Entity
@Getter
@Setter
@Table(name = "food")
public class Food {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private double price;
@OneToMany(mappedBy = "food")
private List<Order> orderList = new ArrayList<>();
}
User Entity
package com.sparta.jpaadvance.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.List;
@Entity
@Getter
@Setter
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy = "user")
private List<Order> orderList = new ArrayList<>();
}
ํ ์คํธ 1
@Test
@Rollback(value = false)
@DisplayName("์ค๊ฐ ํ
์ด๋ธ Order Entity ํ
์คํธ")
void test1() {
User user = new User();
user.setName("Robbie");
Food food = new Food();
food.setName("ํ๋ผ์ด๋ ์นํจ");
food.setPrice(15000);
// ์ฃผ๋ฌธ ์ ์ฅ
Order order = new Order();
order.setUser(user); // ์ธ๋ ํค(์ฐ๊ด ๊ด๊ณ) ์ค์
order.setFood(food); // ์ธ๋ ํค(์ฐ๊ด ๊ด๊ณ) ์ค์
userRepository.save(user);
foodRepository.save(food);
orderRepository.save(order);
}

์กฐํ ํ ์คํธ 2
@Test
@DisplayName("์ค๊ฐ ํ
์ด๋ธ Order Entity ์กฐํ")
void test2() {
// 1๋ฒ ์ฃผ๋ฌธ ์กฐํ
Order order = orderRepository.findById(1L).orElseThrow(NullPointerException::new);
// order ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ์ฌ ๊ณ ๊ฐ ์ ๋ณด ์กฐํ
User user = order.getUser();
System.out.println("user.getName() = " + user.getName());
// order ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ์ฌ ์์ ์ ๋ณด ์กฐํ
Food food = order.getFood();
System.out.println("food.getName() = " + food.getName());
System.out.println("food.getPrice() = " + food.getPrice());
}
