Skip to content

B1ABOA/jpa_study

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

10 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

jpa κ³΅λΆ€ν•΄λ³΄μž!!

πŸ‘©β€πŸ’» νŒ€μ› μ†Œκ°œ

노솔리(🩸AB) λ°•μ›…λΉˆ(🩸A) 이주원(🩸B) ν™λ―Όμ˜(🩸O)
@soljjang777 @Ungbbi @2oo1s @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 μ—”ν‹°ν‹°λŠ” λ‹€μŒκ³Ό 같이 μ •μ˜λ˜μ–΄ μžˆλ‹€κ³  κ°€μ •ν•©λ‹ˆλ‹€:

@Entity
public class Dept {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    // Getters and Setters
}

🎁 μ•„λž˜λŠ” Dept μ—”ν‹°ν‹° 클래슀λ₯Ό μ‚¬μš©ν•˜μ—¬ Dept μ—”ν‹°ν‹°μ˜ λͺ¨λ“  λ ˆμ½”λ“œλ₯Ό κ°€μ Έμ˜€λŠ” JPQL 쿼리의 μ˜ˆμž…λ‹ˆλ‹€:

List<Dept> 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 쿼리 μˆ˜μ •:
List<Dept> datas = em.createQuery("select d from Dept d where d.name = :name", Dept.class)
                    .setParameter("name", "Sales")
                    .getResultList();

예제2

🎁 μ•„λž˜λŠ” Emp μ—”ν‹°ν‹° ν΄λž˜μŠ€μ™€ Emp ν…Œμ΄λΈ”μ— μžˆλŠ” 데이터 μž…λ‹ˆλ‹€.

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

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<Emp> emps = new ArrayList<>();

}

Emp.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<Emp> 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λ₯Ό μ œμ™Έμ‹œμΌœμ£Όλ©΄ λ©λ‹ˆλ‹€.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •  

Languages