Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/b1aboa/jpa_study
https://github.com/b1aboa/jpa_study
Last synced: 5 days ago
JSON representation
- Host: GitHub
- URL: https://github.com/b1aboa/jpa_study
- Owner: B1ABOA
- Created: 2024-08-02T00:31:04.000Z (5 months ago)
- Default Branch: main
- Last Pushed: 2024-08-04T07:20:24.000Z (5 months ago)
- Last Synced: 2024-11-08T22:39:58.435Z (about 2 months ago)
- Language: Java
- Size: 28.3 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# jpa 공부해보자!!
## 👩💻 팀원 소개
| 노솔리(🩸AB) | 박웅빈(🩸A) | 이주원(🩸B) | 홍민영(🩸O) |
| :-------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------: |
| | | | |
| [@soljjang777](https://github.com/soljjang777) | [@Ungbbi](https://github.com/Ungbbi) | [@2oo1s](https://github.com/2oo1s) | [@HongMinYeong](https://github.com/HongMinYeong) |# Entity
## Emp Table
| Field | Type | Null | Key | Default | Extra |
| --- | --- | --- | --- | --- | --- |
| EMPNO | int | NO | PRIMARY KEY | | |
| COMM | int | YES | | | |
| ENAME | String | YES | | | |
| JOB | String | YES | | | |
| HIERDATE | String | YES | | | |
| SAL | int | YES | | | |
| MGR | int | YES | | | |
| DEPTNO | int | YES | FOREIGN KEY | | |
## Dept Table
| Field | Type | Null | Key | Default | Extra |
| --- | --- | --- | --- | --- | --- |
| DEPTNO | int | NO | PRIMARY KEY | | |
| DNAME | String | YES | | | |
| LOC | String | YES | | | |
## 예제1
### 🎁 `Dept` 엔티티는 다음과 같이 정의되어 있다고 가정합니다:
```java
@Entity
public class Dept {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;private String name;
// Getters and Setters
}
```### 🎁 아래는 Dept 엔티티 클래스를 사용하여 `Dept` 엔티티의 모든 레코드를 가져오는 JPQL 쿼리의 예입니다:
```java
List datas = em.createQuery("select d from Dept d", Dept.class).getResultList();
```
### 🎱 문제입니다!:
1. **JPQL 쿼리에서 `Dept.class`를 사용하여 `Dept` 타입으로 결과를 가져오는 이유는 무엇인가요?**
2. **위의 JPQL 쿼리를 사용하여 `Dept` 엔티티의 `name` 필드가 "Sales"인 모든 `Dept` 객체를 조회하려면 쿼리를 어떻게 수정해야 하나요?**### 답안
1. Dept.class를 사용하는 이유| Dept.class를 사용하는 이유는 createQuery 메서드의 두 번째 인자로 결과 타입을 지정하여 반환된 결과가 Dept 타입으로 캐스팅되도록 하기 위함입니다 -> 이는 타입 안전성을 보장합니다.
2. name 필드가 "Sales"인 Dept 객체를 조회하는 JPQL 쿼리 수정:```java
List datas = em.createQuery("select d from Dept d where d.name = :name", Dept.class)
.setParameter("name", "Sales")
.getResultList();
```## 예제2
### 🎁 아래는 Emp 엔티티 클래스와 Emp 테이블에 있는 데이터 입니다.
```java
package model.domain.entity;import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.ToString;@AllArgsConstructor
@NoArgsConstructor
@RequiredArgsConstructor
@Getter
@Setter
//@ToString@Table(name = "emp")
@Entity
public class Emp {
@Id
@Column(name = "empno")
private long empno;
@NonNull
private String ename;
@NonNull
private String job;
@NonNull
private int mgr;@NonNull
private Date hiredate;
@NonNull
private int sal;
private int comm;
@OneToOne
@JoinColumn(name="deptno")
private Dept deptno;
}```
### 🎱 문제입니다!:
현재 Dept객체로 Select시 위와 같은 에러가 발생하는데 왜 나는것일까요??### 답안
> emp 테이블의 mgr와 sal 컬럼에 null 값이 포함된 것을 확인할 수 있습니다. 현재 Emp 엔티티를 생성할 때 mgr과 sal의 데이터 타입을 int로 설정하였는데, int 타입은 null 값을 허용하지 않습니다.
> 따라서, 만약 데이터베이스에서 mgr이나 sal이 null인 경우, 엔티티에서 이를 처리할 수 없게 됩니다.
> 이를 해결하기 위해 mgr과 sal의 데이터 타입을 Integer로 변경해야 합니다. Integer는 null 값을 허용하는 래퍼 클래스이므로,
> 데이터베이스에서 null 값을 포함할 수 있는 컬럼을 적절히 처리할 수 있습니다. 이 변경을 통해 null 값이 있을 경우에도 Emp 엔티티가 정상적으로 동작할 수 있게 됩니다.
# 💥 Issue
- Import 문은 제외하였습니다.
### Dept.java
```java
package model.domain.entity;@AllArgsConstructor
@NoArgsConstructor
@RequiredArgsConstructor
@Getter
@Setter
@ToString@Table(name = "dept")
@Entity
public class Dept {
@Id
@Column(name = "deptno")
private long deptno;
@NonNull
private String dname;
@NonNull
private String loc;
@OneToMany(mappedBy = "deptno")
private List emps = new ArrayList<>();}
```
### Emp.java
```java
package model.domain.entity;@AllArgsConstructor
@NoArgsConstructor
@RequiredArgsConstructor
@Getter
@Setter
@ToString@Table(name = "emp")
@Entity
public class Emp {
@Id
@Column(name = "empno")
private long empno;
@NonNull
private String ename;
@NonNull
private String job;
@NonNull
private int mgr;@NonNull
private Date hiredate;
@NonNull
private int sal;
private int comm;
@OneToOne
@JoinColumn(name="deptno")
private Dept deptno;
}```
### RunningTest.java
```
public class RunningTest {
@Test
public void stpe01Test() {
EntityManager em = DBUtil.getEntityManager();
Emp emp = em.find(Emp.class, 7782L);
System.out.println("사원 아이디가 7782 사람 : " + emp.getEname());
System.out.println("사원 아이디가 7782 사람 : " + emp.getEname() + " / 부서명 : " + emp.getDeptno().getDeptno());
System.out.println("사원 아이디가 7782 사람 : " + emp.getDeptno());
Dept dept = em.find(Dept.class, 10L);
System.out.println("부서 아이디가 10인 부사 : " + dept.getDname());
List emps = dept.getEmps();
emps.forEach(System.out::println);
em = null;
}}
```
### 🎱 문제입니다!:
RunningTest.java 에서 System.out.println 으로 Deptno를 출력하고자 하면 Stackoverflow error가 발생합니다. 왜일까요?### 답안
> 순환 참조
> 원인 : ToString으로 인해 발생하게 되는 에러입니다.
> 1. Emp 객체와 Dept 객체가 있습니다.
> 2. Emp 객체는 Dept 객체를 참조합니다 (emp.getDeptno()).
> 3. Dept 객체도 여러 Emp 객체들을 리스트로 참조합니다 (dept.getEmps()).
>
> 즉, Emp 객체가 Dept 객체를 포함하고, Dept 객체가 다시 여러 Emp 객체들을 포함하는 구조입니다.
> emp.toString()이 호출되면 Dept 객체의 toString()이 호출되고, 이 Dept 객체의 toString()은 다시 그 안에 포함된 여러 Emp 객체들의 toString()을 호출하게 됩니다.> 쉽게 표현하자면
> emp.toString() -> dept.toString() -> emps.toString() -> 다시 emp.toString()으로 무한히 순환하면서 호출됩니다.
> 이로 인해 StackOverflowError와 같은 에러가 발생하게 되는 것입니다.### Solution
> 두 클래스파일 중 한 곳에 ToString(exclude = )로 순환참조가 발생하게되는 멤버변수를 제외시켜줍시다.
> 예를 들자면 Dept 클래스에서 해결해주고자 한다면
> @ToString(exclude = "emps")
> 위와 같이 순환 참조가 발생하게 되는 emps를 제외시켜주면 됩니다.