Skip to content

Commit

Permalink
Dynamodb 이전 블로그 글 백업
Browse files Browse the repository at this point in the history
  • Loading branch information
5jisoo committed Oct 22, 2024
1 parent 573482e commit 30ae381
Show file tree
Hide file tree
Showing 5 changed files with 525 additions and 1 deletion.
56 changes: 56 additions & 0 deletions _posts/2023-08-10-spring-data-dynamodb-localdatetime.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
title: LocalDateTime 저장 에러
date: 2023-08-10 18:20:00 +/-TTTT
categories: [Spring, Spring Data DynamoDB]
tags: [spring, dynamodb, troubleshooting] # TAG names should always be lowercase
---

## 문제 상황

LocalDateTime을 DynamoDB에 저장하려고 했으나, 다음과 같은 에러가 발생하였습니다.

```
InvalidDefinitionException: Joda date/time type `org.joda.time.LocalDateTime` not supported by default
```

## 해결 과정

LocalDateTime parsing 에러로 추측하였으며,

직접 LocalDateTime을 바꿔주는 Custom Converter를 작성하여 해당 에러를 해결해 줄 수 있었습니다.

```java
public static class LocalDateTimeConverter implements DynamoDBTypeConverter<Date, LocalDateTime> {
@Override
public Date convert(LocalDateTime source) {
return Date.from(source.toInstant(ZoneOffset.UTC));
}

@Override
public LocalDateTime unconvert(Date source) {
return source.toInstant().atZone(TimeZone.getDefault().toZoneId()).toLocalDateTime();
}
}
```

이후, 사용하고자 하는 Entity에 적용해주면 됩니다.

- POCHAK의 경우, BaseEntity의 LocalDateTime attribute에 **@DynamoDBTypeConverted(converter = LocalDateTimeConverter.class)** 애노테이션을 추가해주었습니다.

```java
public class BaseEntity {

...

@LastModifiedDate
@DynamoDBAttribute
@DynamoDBTypeConverted(converter = LocalDateTimeConverter.class)
private LocalDateTime lastModifiedDate;

...
}
```

## 참고 자료

- [Spring Boot에서 Repository로 DynamoDB 조작하기 - 우아한 기술 블로그](https://techblog.woowahan.com/2633/)
112 changes: 112 additions & 0 deletions _posts/2023-08-10-spring-data-dynamodb-partitionkey-and-sortkey.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
---
title: Partition Key와 Sort Key를 같이 사용할 때
date: 2023-08-10 18:20:00 +/-TTTT
categories: [Spring, Spring Data DynamoDB]
tags: [spring, dynamodb, troubleshooting] # TAG names should always be lowercase
---

## 문제 상황

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

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

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

## 문제 해결 과정

### UserId Class

- UserId 클래스를 다음과 같이 설정합니다. User에서 설정한 PK와 SK의 조합으로 이루어집니다.
- 유의할 점은 UserId 클래스는 Serializable을 구현`implements`해야 합니다.

```java
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 클래스는 꼭 다음과 같이 **지연 생성**을 해주어야 합니다.

```java
@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 클래스 - 를 사용해야 합니다.

```java
@EnableScan
public interface UserCrudRepository extends DynamoDBCrudRepository<User, UserId> {
}
```

## 참고 자료

- [Use Hash Range Keys - derjust:spring-data-dynamodb](https://github.com/derjust/spring-data-dynamodb/wiki/Use-Hash-Range-keys)
Loading

0 comments on commit 30ae381

Please sign in to comment.