져니의 개발 정원 가꾸기

DynamoDB 사용시 마주치는 Exception 모음 zip. (feat AWS SDK) 본문

개발노트/dynamoDB

DynamoDB 사용시 마주치는 Exception 모음 zip. (feat AWS SDK)

전전쪄니 2024. 9. 1. 11:06

1. software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException: Requested resource not found (Service: AmazonDynamoDB; Status Code: 400; Error Code: ResourceNotFoundException; Request ID

 

Why)

말그대로 리소스를 못찾겠다는 익셉션.

aws cli로 실제로 존재하지 않는 테이블을 찾으려고 하니 다음과 같은 메시지가 출력된다.

aws dynamodb scan --table-name other-data --endpoint-url http://localhost:8000

An error occurred (ResourceNotFoundException) when calling the Scan operation: Cannot do operations on a non-existent table

Sol)

- 접근하는 테이블이 실제로 생성되어 있는지 확인하자.

- region, accessKey, secretKey를 맞게 썼는지 확인하자.

참고 : https://stackoverflow.com/questions/40192304/aws-dynamodb-resource-not-found-exception 

 

2. software.amazon.awssdk.services.dynamodb.model.DynamoDbException: The provided key element does not match the schema

 

Why) 

실제 DynamoDb 테이블의 스키마와 다이나모디비 객체에 선언한 key(@DynamoDbPartitionKey, @DynamoDbSortKey)가 안 맞을 경우(ex. 타입, 이름)

 

Sol)

dynamoDb가 비정형 데이터를 저장할 수 있지만, key의 타입, 이름은 반드시 맞춰줘야 한다.

(이 경우는 필수 데이터로 partitionKey와 sortKey 만을 사용하여 key에 대한 익셉션만 떴는데

만약 paritionKey와 sortKey말고도 필수로 사용하는 속성(attribute)가 있다면 해당하는 속성도 매핑객체의 필드로 반드시 포함시켜야 한다.)

 

실제 테이블과 매핑객체의 이름을 맞추기

> @DynamoDbPartitionKey, @DynamoDbSortKey가 선언된 getter에  @DynamoDbAttribute("실제 테이블의 속성 이름") 선언 

 

적합한 타입 정의하기

> 아래 링크 참고

https://docs.aws.amazon.com/ko_kr/amazondynamodb/latest/developerguide/DynamoDBMapper.DataTypes.html

 

3. Caused by: java.lang.IllegalArgumentException: Class 'class com.org.test.domain.enums.ProcessStatus' appears to have no default constructor thus cannot be used with the BeanTableSchema

Why)

enum class를 직렬화/역직렬화 하려고 할 때 적합한 컨버터가 없어서 생기는 에러.

다음과 같이 UserType이라는 enum class가 있고 UserType타입의 필드를 선언한 User 다이나모디비 매핑 객체와 dynamoDbClient(혹은 dynamoDbEnhancedClient)를 사용하여 연산하려고 한다고 하자.

public enum UserType {
    ADMIN("admin", 10000),
    GUEST("guest", 20000)
    CUSTOMER("customer", 20001),
    ENTP_CUSTOMER("enterprise_customer", 20002),
    SELLER("seller", 30001),
    ...
}
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable;

@DynamoDBTable(tableName = "UserItem")
public class UserItem {

    private String userId;
    private UserType userType;

    @DynamoDBHashKey(attributeName = "UserId")
    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    @DynamoDBAttribute(attributeName = "UserType")
    public UserType getUserType() {
        return userType;
    }

    public void setUserType(UserType userType) {
        this.userType = userType;
    }
}

 

> enum의 name 값(ADMIN, CUSTOMER...)를 저장하려고 할 때 직렬화, 역직렬화하는 Converter가 없기 때문에 발생하는 익셉션이다.

 

Sol)

1. . AttributeConverter<타입> 을 implements 하는 클래스를 생성한다.

public class UserTypeConverter implements AttributeConverter<UserType> {
    ...
}

2. 매핑시킬 다이나모 객체에서 사용할 컨버터들을 소유하는 AttributeConverterProvider   를 implements 하는 클래스를 만든다. 그리고 1에서 만든 컨버터는 컨버터들을 담고 있는 Map 필드에 추가한다.

    public static final class UserTypeConverter implements AttributeConverter<UsertType> {

        @Override
        public AttributeValue transformFrom(UserType userType) {
            ...
        }

        @Override
        public UserType transformTo(AttributeValue attributeValue) {
            ...
        }

        @Override
        public EnhancedType<UserType> type() {
            return EnhancedType.of(UserType.class);
        }

        @Override
        public AttributeValueType attributeValueType() {
            return AttributeValueType.M;
        }
    }

3. @DynamoDbBean이 선언된 다이나모디비 매핑 객체에 2번에서 만든 converterProvider를 추가한다.

@DynamoDbBean(converterProviders = {
   UserTypeConverter.class, 
   DefaultAttributeConverterProvider.class})
public class User {
    ...
}

 

자세한 내용은 아래 공식문서 가이드를 참고

> https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-adv-features-conversion.html