Post

Partition Key와 Sort Key를 같이 사용할 때

문제 상황

POCHAK은 원테이블 설계로, Partition KeySort Key를 모두 사용하여 설계하였습니다.

하지만 Spring Data DynamoDB와 연결하는 과정에서 BeanCreationException이 발생하였습니다.

이를 해결하기 위해 알아보는 과정에서 Partition Key와 Sort Key를 같이 사용하는 경우, CrudRepository를 사용할 때 PK와 SK를 조합한 Id 클래스가 따로 있어야 한다는 점을 알게되고 에러를 해결한 과정을 정리합니다!

문제 해결 과정

UserId Class

  • UserId 클래스를 다음과 같이 설정합니다. User에서 설정한 PK와 SK의 조합으로 이루어집니다.
  • 유의할 점은 UserId 클래스는 Serializable을 구현implements해야 합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class UserId implements Serializable {
    private static final long serialVersionUID = 1L;

    private String handle;
    private String userSK = "USER#";

    @DynamoDBHashKey
    public String getHandle() {
        return handle;
    }

    public void setHandle(String handle) {
        this.handle = handle;
    }

    @DynamoDBRangeKey
    public String getUserSK() {
        return userSK;
    }

    public void setUserSK(String userSK) {
        this.userSK = userSK;
    }
}

User Class

User의 PK, SK의 getter, setter를 ID에서 받아오고(getter), ID을 변경하도록(setter) 설정해줍니다.

  • 참고로 보통 모든 Entity의 attribute는 SDK에서 사용하기 위해서 getter와 setter를 필수로 가지고 있어야 합니다. 다만, userId는 getter와 setter가 있어서는 안됩니다.
  • 이 외에도 ID 클래스는 꼭 다음과 같이 지연 생성을 해주어야 합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
@NoArgsConstructor
@DynamoDBTable(tableName = "pochakdatabase")
public class User extends BaseEntity {

    @Id // ID class should not have getter and setter.
    private UserId userId;

    private String handle; // PK

    private String userSK; // SK

    ...

    @DynamoDBHashKey(attributeName = "PartitionKey")
    public String getHandle() {
        return userId != null ? userId.getHandle() : null;
    }

    public void setHandle(String handle) {
        if (userId == null) {
            userId = new UserId();
        }
        userId.setHandle(handle);
    }

    @DynamoDBRangeKey(attributeName = "SortKey")
    public String getUserSK() {
        return userId != null ? userId.getUserSK(): null;
    }

    public void setUserSK(String userSK) {
        if (userId == null) {
            userId = new UserId();
        }
        userId.setUserSK(userSK);
    }
 ...
}

UserCrudRepository interface

이렇게 설정하면 CrudRepository를 구현하는 UserCrudRepository 클래스는 다음과 같이 작성할 수 있습니다.

  • 저장소는 꼭 ID 클래스 - 여기서는 UserId 클래스 - 를 사용해야 합니다.
1
2
3
@EnableScan
public interface UserCrudRepository extends DynamoDBCrudRepository<User, UserId> {
}

참고 자료

This post is licensed under CC BY 4.0 by the author.