java.lang.IllegalArgumentException: Provided id of the wrong type for class step04.onetomany.Team4. Expected: class java.lang.Long, got class java.lang.Integer
Caused by: org.hibernate.TypeMismatchException: Provided id of the wrong type for class step04.onetomany.Team4. Expected: class java.lang.Long, got class java.lang.Integer
@Test
public void step02Test() {
EntityManager em = DBUtil.getEntityManager();
Team4 team = em.find(Team4.class, 1); // ?
System.out.println(team.getTeamName());
em.close();
}
step01 - team 검색
1 - 정수(int, 32bit) / Team4의 pk 변수는 long(64 bit)
int -> long으로 자동 형변환 (기본 타입의 기질)
Integer 와 Long 객체타입 자동형변환 불가
1 -> new Integer(1) 자동변환
문제는 Integer가 아닌 Long 타입이 필요 따라서 Long 객체로 변환 가능한 값 표현
long 값 표현시 l or L
autoboxing 때문에
오토박싱(autoboxing)은 자바에서 기본 데이터 타입(primitive types)과 그에 대응하는 래퍼 클래스(wrapper classes) 간의 자동 변환을 수행하는 기능입니다. 자바에서 기본 데이터 타입은 `int`, `char`, `double` 등이 있으며, 래퍼 클래스는 이 기본 타입들을 객체로 감싸는 클래스들입니다. 예를 들어, `Integer`는 `int`, `Double`은 `double`을 감쌉니다.
오토박싱은 기본 타입을 래퍼 클래스로 자동 변환할 때 사용됩니다. 예를 들어:
int num = 10; // 기본 타입
Integer numObj = num; // 오토박싱으로 int를 Integer로 변환
위의 코드에서 `num` (기본 타입 `int`)은 컴파일러에 의해 자동으로 `Integer` 객체로 변환됩니다.
언박싱(unboxing)은 래퍼 클래스를 기본 타입으로 자동 변환하는 과정입니다:
Integer numObj = 10; // 오토박싱
int num = numObj; // 언박싱으로 Integer를 int로 변환
여기서 `numObj` (래퍼 클래스 `Integer`)는 자동으로 기본 타입 `int`로 변환됩니다.
주요 포인트:
* 오토박싱과 언박싱은 기본 타입과 객체 기반 API 간의 상호 작용을 간편하고 직관적으로 만들어줍니다.
* 제네릭(Generics)과 같은 API를 사용할 때 특히 유용합니다. 제네릭은 기본 타입을 직접 처리할 수 없기 때문에 객체가 필요합니다.
사용 예제:
List<Integer> numbers = new ArrayList<>();
numbers.add(5); // 오토박싱이 여기서 발생
int firstNumber = numbers.get(0); // 언박싱이 여기서 발생
위의 예제에서 `5` (기본 타입 `int`)는 `List`에 추가될 때 자동으로 `Integer` 객체로 변환되고, `List`에서 값을 꺼낼 때는 다시 기본 타입 `int`로 자동 변환됩니다.
오토박싱과 언박싱은 기본 타입과 객체 기반 API 간의 상호작용을 단순화하여 자바 언어를 더 유연하고 사용하기 쉽게 만들어줍니다.
@ManyToOne(fetch = FetchType.LAZY)
- FetchType.LAZY : 관련 엔티티가 명시적으로 접근될 때까지 데이터베이스에서 로드되지 않음
- 데이터가 필요할 때만 로드, 불필요한 데이터베이스 쿼리를 피할 수 있음
- 즉시 필요한 데이터만 로드, 메모리 사용 줄일 수 있음
JPA에서 `@ManyToOne` 관계를 설정할 때, `fetch` 속성을 `FetchType.EAGER`로 지정하거나, `fetch` 설정을 아예 하지 않는 경우의 차이점을 설명하겠습니다.
`FetchType.EAGER`
- 즉시 로딩: `FetchType.EAGER`를 사용하면, 관련된 엔티티가 쿼리 시 즉시 로드됩니다. 즉, 부모 엔티티를 로드할 때, 자식 엔티티도 함께 로드됩니다.
- 쿼리 성능: 관련된 엔티티를 즉시 로드하기 때문에, 초기 쿼리에서 모든 관련 데이터를 한 번에 가져옵니다. 이로 인해 성능 저하가 발생할 수 있지만, 엔티티를 사용할 때 추가 쿼리가 발생하지 않습니다.
- 메모리 사용: 모든 관련 데이터를 한 번에 로드하므로, 메모리 사용량이 늘어날 수 있습니다.
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "customer_id")
private Customer customer;
`FetchType.LAZY`와 fetch 설정 없는 경우
- 지연 로딩: `FetchType.LAZY`를 사용하거나 `fetch` 속성을 명시하지 않을 경우, 기본적으로 `@ManyToOne` 관계는 지연 로딩이 됩니다. 이는 부모 엔티티를 로드할 때 자식 엔티티를 로드하지 않고, 실제로 자식 엔티티에 접근할 때까지 데이터베이스에서 로드하지 않는 것을 의미합니다.
- 쿼리 성능: 자식 엔티티를 필요로 할 때까지 쿼리가 발생하지 않기 때문에 초기 쿼리의 성능을 개선할 수 있습니다. 그러나 자식 엔티티에 접근할 때 추가적인 쿼리가 발생할 수 있습니다.
- 메모리 사용: 필요한 데이터만 로드하므로 메모리 사용이 더 효율적일 수 있습니다.
@ManyToOne
@JoinColumn(name = "customer_id")
private Customer customer;
요약
- `FetchType.EAGER`: 관련된 엔티티를 즉시 로드하므로 초기 쿼리에서 모든 데이터를 가져옵니다. 성능이 저하될 수 있지만, 추가 쿼리가 발생하지 않습니다.
- `FetchType.LAZY` (또는 설정이 없는 경우): 관련된 엔티티는 실제로 필요할 때까지 로드하지 않습니다. 초기 쿼리 성능이 향상되지만, 추가 쿼리가 발생할 수 있습니다.
둘 중 어떤 것을 선택할지는 애플리케이션의 요구 사항과 데이터 접근 패턴에 따라 다릅니다. `FetchType.EAGER`는 모든 관련 데이터를 한 번에 가져오지만, `FetchType.LAZY`는 필요한 데이터만 나중에 가져와서 성능과 메모리 사용을 더 효율적으로 관리할 수 있습니다.
'FISA 3기' 카테고리의 다른 글
| Page 이동 방식 (0) | 2024.08.07 |
|---|---|
| 비동기 처리 기술 학습 (1) | 2024.08.07 |
| 토크콘서트 요약 (0) | 2024.07.31 |
| STS에서 Gradle 프로젝트 만들기 (2) | 2024.07.30 |
| Logstash에 MySQL 연동하기 (0) | 2024.07.25 |