728x90
반응형
SMALL

#### 발생 원인:

- **타입 불일치**: 쿼리 결과에서 `employeesName` 컬럼은 문자열 타입인데, 해당 컬럼을 `int`로 처리하려고 시도하여 `SQLException`이 발생.
    - **에러 메시지**:

1. ResultSet.getInt(employeesName) java.sql.SQLException: Out of range value for column 'employeesName': value 박현아


    - **문제**: `employeesName` 컬럼의 값이 실제로는 문자열(`"박현아"`)인데, 이를 `int`로 변환하려고 시도했기 때문에 타입 불일치 오류가 발생.

#### 영향 범위:

- **데이터 매핑 오류**: `employeesName` 값을 `int`로 처리하려고 시도했기 때문에 데이터 매핑이 올바르게 처리되지 않음. 이는 `employeesName`을 사용하는 모든 로직에서 오류를 발생시킴.
- **응답 실패**: 쿼리 결과를 처리하는 과정에서 `SQLException`이 발생하여 애플리케이션이 예상대로 동작하지 않음.
- **타입 불일치**: 데이터베이스 컬럼의 타입과 Java 모델 객체의 타입이 일치하지 않아서, 데이터를 가져오는 과정에서 오류가 발생.

#### 주요 프로세스 영향:

1. **데이터 조회 실패**:
    - `ResultSet.getInt()` 메소드에서 `employeesName` 값을 `int`로 읽으려 했지만, 컬럼이 문자열이므로 `SQLException`이 발생. 이로 인해 데이터 조회가 실패함.
2. **잘못된 모델 매핑**:
    - 모델 객체에서 `employeesName` 필드를 `int`로 선언한 경우, 데이터베이스에서 문자열 값을 올바르게 매핑할 수 없어서 오류가 발생.
3. **응답 지연**:
    - 쿼리 실행 중 오류가 발생하여 응답을 제대로 반환할 수 없게 되고, 클라이언트에 오류 응답이 전송됨.

#### 해결 방안:

1. **모델 수정**:
    
    - `employeesName` 컬럼의 값을 올바르게 처리할 수 있도록 모델 객체에서 `employeesName` 필드를 `String` 타입으로 변경.
    - **수정된 코드**:

private String employeesName;  // String 타입으로 수정


2. **타입 일치 검토**:
    
    - 데이터베이스 컬럼 타입과 Java 모델 타입이 일치하는지 항상 확인해야 하며, 쿼리 결과를 매핑할 때 타입 불일치가 발생하지 않도록 유의.
    - 문자열 값을 `int`로 변환하려고 할 경우, 해당 컬럼이 실제로 숫자 값임을 확인한 후 변환해야 합니다.
3. **테스트 및 검증**:
    
    - 모델 타입을 변경한 후, 데이터베이스에서 쿼리를 실행하고 모델 객체에 데이터를 제대로 매핑할 수 있는지 테스트.
    - 다양한 문자열 데이터를 테스트하여 오류가 발생하지 않는지 확인.
4. **로깅 및 예외 처리**:
    
    - `SQLException`이 발생할 가능성이 있는 경우, 적절한 예외 처리와 로깅을 추가하여 문제 발생 시 빠르게 원인을 추적할 수 있도록 함.
    - 예를 들어, `SQLException`을 잡아서 상세한 오류 메시지를 로깅할 수 있습니다.
5. **쿼리 최적화**:
    
    - 쿼리에서 필요한 컬럼만 선택적으로 조회하거나, 데이터 타입에 맞는 필드를 사용하여 쿼리 성능을 최적화할 수 있습니다.

#### 결론:

`employeesName` 컬럼의 값을 `int` 타입으로 처리하려고 시도하여 발생한 `SQLException`을 해결하기 위해, Java 모델 객체에서 `employeesName` 필드를 `String` 타입으로 변경해야 합니다. 이를 통해 데이터베이스에서 반환되는 문자열 값을 올바르게 처리할 수 있습니다. 타입 일치를 확인하고, 예외 처리를 적절히 적용하여 데이터 조회 오류를 예방해야 합니다.

728x90
반응형
LIST
728x90
반응형
SMALL

### 에러 노트: NullPointerException - 포인트 값이 없을 경우

#### 발생 원인:

- **`NullPointerException` 발생**: `MobilePoint` 객체가 `null`일 경우, `point.getPoint()` 메소드 호출에서 `NullPointerException`이 발생.
    - **기존 코드**:

        return new PageImpl<>(list.getResults().stream()       
        .map(tuple -> {           
        MobileUsers data = tuple.get(userInfo);           
        MobilePoint point = tuple.get(userPoint);           
        return new MobileUserDTO.UserListData(               
        point.getPoint()          
        );       
        })       
        .collect(Collectors.toList()), pageable, list.getTotal());


        
    - **문제**: `point`가 `null`일 때 `point.getPoint()`를 호출하려고 해서 `NullPointerException`이 발생.
    - **해결 코드**:

        return new PageImpl<>(list.getResults().stream()       
            .map(tuple -> {           
            MobileUsers data = tuple.get(userInfo);           
        MobilePoint point = tuple.get(userPoint);           
        return new MobileUserDTO.UserListData(               
        point != null && point.getPoint() != null ? point.getPoint() : 0               
        // point가 null일 경우 0 반환           
        );       
        })       
        .collect(Collectors.toList()), pageable, list.getTotal());


#### 영향 범위:

- **NullPointerException**: `MobilePoint` 객체가 `null`일 경우, `point.getPoint()` 호출 시 예외가 발생하여 애플리케이션이 중단될 수 있음.
- **데이터 처리 오류**: `point`가 `null`인 경우에도 `getPoint()`를 안전하게 처리하지 않으면, 해당 사용자에 대한 데이터를 처리할 수 없거나, 오류가 발생하여 결과가 정상적으로 반환되지 않음.

#### 주요 프로세스 영향:

1. **데이터 조회 실패**:
    - `MobilePoint` 객체가 `null`인 경우, `point.getPoint()` 호출에서 오류가 발생하여, 해당 사용자의 정보가 잘못 처리되거나 조회되지 않음.
2. **응답 지연**:
    - 예외가 발생하여 요청이 실패하거나 예외 처리 로직으로 넘어가게 되어, 응답 시간이 지연될 수 있음.
3. **서비스 장애**:
    - `NullPointerException`으로 인해 서비스가 중단되거나, 일부 기능이 정상적으로 작동하지 않음.

#### 해결 방안:

1. **`null` 체크 추가**:
    
    - `MobilePoint` 객체가 `null`일 경우, `getPoint()`를 호출하지 않도록 `null` 체크를 추가하여 `NullPointerException`을 방지.
    - `point`가 `null`일 경우에는 기본 값(예: `0`)을 반환하도록 처리.
    - **수정된 코드**:

return new PageImpl<>(list.getResults().stream()       
  .map(tuple -> {           
  MobileUsers data = tuple.get(userInfo);           
  MobilePoint point = tuple.get(userPoint);           
return new MobileUserDTO.UserListData(               
point != null && point.getPoint() != null ? point.getPoint() : 0               
// point가 null일 경우 0 반환           
);       
})       
.collect(Collectors.toList()), pageable, list.getTotal());


        
2. **`Optional` 사용**:
    
    - `Optional`을 사용하여 `null` 처리를 더 안전하게 할 수 있음. 예를 들어, `point.getPoint()` 대신 `Optional.ofNullable(point).map(MobilePoint::getPoint).orElse(0)`와 같이 처리할 수 있음.
       

   return new PageImpl<>(list.getResults().stream()       
   .map(tuple -> {           
   MobileUsers data = tuple.get(userInfo);           
   MobilePoint point = tuple.get(userPoint);           
   return new MobileUserDTO.UserListData(               
   Optional.ofNullable(point).map(MobilePoint::getPoint).orElse(0)           
   );       
   })       
   .collect(Collectors.toList()), pageable, list.getTotal());


        
3. **테스트 및 검증**:
    
    - 수정된 코드가 정상적으로 동작하는지 확인하기 위해, `point`가 `null`인 경우와 아닌 경우에 대해 다양한 테스트를 진행.
    - 특히 `point`가 `null`일 때 결과가 `0`으로 반환되는지 검증.
4. **로깅**:
    
    - `point`가 `null`인 경우에 대한 로깅을 추가하여, 데이터가 `null`인 이유와 함께 문제를 추적할 수 있도록 함.
    - 예시:

if (point == null) {     
log.warn("MobilePoint is null for user: {}",data.getId()); 
}



#### 결론:

`MobilePoint` 객체가 `null`일 경우 `getPoint()` 메소드 호출에서 `NullPointerException`이 발생하는 문제를 해결하기 위해 `null` 체크를 추가하여 안전하게 처리하도록 수정해야 합니다. `Optional`을 사용하면 코드가 더 깔끔하고 안전하게 `null` 값을 처리할 수 있습니다. 이를 통해 애플리케이션이 중단되지 않고 정상적으로 데이터를 처리할 수 있습니다.

728x90
반응형
LIST
728x90
반응형
SMALL

변수가 초기화되지 않았을 수 있습니다.

 


private final UserServiceImpl userService;

private UserServiceImpl userService;

로 변경하면 적용은 됨 작동하는지 확인 필요

 

@RequiredArgsConstructor

를 컨트롤러와 서비스단에 만들어주지 않아서 생긴 문제였다....쩝..

 

**@RequiredArgsConstructor**는 Java 언어에서 Lombok이라는 라이브러리를 통해 제공되는 어노테이션

어노테이션을 사용하면 생성자를 자동으로 생성해주는 기능을 제공!

Lombok은 반복적이고 번거로운 작업을 줄여주기 위해 개발자들이 자주 사용하는 여러 어노테이션들을 제공하는 유용한 라이브러리이다.

@RequiredArgsConstructor 어노테이션은 주로 불변(immutable) 클래스에서 사용된다. 불변 클래스란 한 번 생성된 객체가 그 상태를 변경할 수 없는 클래스를 의미한다. 이런 클래스는 객체의 무결성을 보장하고 예측 가능한 동작을 강조하는 데 유용하다.

이 어노테이션은 클래스의 final 필드들을 기반으로 생성자를 자동으로 생성한다. 클래스의 모든 final 필드를 매개변수로 받는 생성자를 생성해주며, 이를 통해 객체를 생성할 때 필수적인 값들을 지정할 수 있다.

예를 들어, 아래와 같이 @RequiredArgsConstructor 어노테이션을 사용한 경우!

import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
public class Person {
    private final String firstName;
    private final String lastName;
    private int age;
}

위 코드에서 @RequiredArgsConstructor 어노테이션이 적용된 Person 클래스는 **firstName**과 lastName 필드를 기반으로 생성자를 자동으로 생성한다. 생성자는 불변 필드들을 인자로 받으며, 나머지 age 필드는 생성자에 포함되지 않는다.

이렇게 생성자를 자동으로 생성하면 객체를 초기화할 때 필요한 값들을 간편하게 전달할 수 있다. 이와 함께 Lombok은 다양한 다른 어노테이션들을 제공하여 코드 작성을 더욱 간결하게 만들어준다.

728x90
반응형
LIST

+ Recent posts