채팅메시지를 레디스에 저장시 저장이 안되고 아래와 같은 오류가 발생
채팅메시지를 Redis에 저장 시 저장이 안되는 오류 발생
오류내용 : org.springframework.data.redis.serializer.SerializationException: Cannot serialize;
채팅메시지를 레디스에 저장후 1:1 채팅방 및 경매 게시글 채팅방에서 나갔다 들어왔을때 아래의 오류 내용이 발생
채팅메시지 Redis 저장 후 1:1 채팅방에 입장후 퇴장 시 오류 발생
오류내용 : Java 8 date/time type java.time.LocalDateTime not supported by default
위의 오류 내용(org.springframework.data.redis.serializer.SerializationException: Cannot serialize;)을 구글링해서 알아본 결과 레디스에 저장 및 조회 할 시 직렬화와 역직렬화가 필요한데 이 기능이 정상적으로 작동하지 않는 것으로 확인. —> 직렬화의 문제
Redis에 저장 및 조회 시 직렬화/역직렬화가 필요한데 제대로 작동 안하는 문제
//redis 에 메세지 저장하기
@Transactional
public ChatMessage save(ChatMessage chatMessage) {
//chatMessageDto 를 redis 에 저장하기 위하여 직렬화 한다.
//===================================================================
//===================================================================
// 이부분에서 위와 같은 오류가 발생함.
redisTemplate.setValueSerializer(
new Jackson2JsonRedisSerializer<>(ChatMessage.class));
//===================================================================
//===================================================================
String roomId = chatMessage.getRoomId();
//redis에 저장되어있는 리스트를 가져와, 새로 받아온 chatmessageDto를 더하여 다시 저장한다.
List<ChatMessage> chatMessageList = opsHashChatMessage.get(CHAT_MESSAGE, roomId);
//가져온 List가 null일때 새로운 리스트를 만든다 == 처음에 메세지를 저장할경우 리스트가 없기때문에.
if (chatMessageList == null) {
chatMessageList = new ArrayList<>();
}
chatMessageList.add(chatMessage);
//redis 의 hashes 자료구조
//key : CHAT_MESSAGE , filed : roomId, value : chatMessageList
opsHashChatMessage.put(CHAT_MESSAGE, roomId, chatMessageList);
System.out.println();
redisTemplate.expire(CHAT_MESSAGE,24, TimeUnit.HOURS);
System.out.println("===========================ChatMessage save 시간 :"
+ chatMessage.getCreatedAt());
return chatMessage;
}
1번의 문제에 관한 선택지
내가 코드를 잘못 입력했을 가능성(코드에 직렬화를 제대로 하지 못함.)
—> 충분히 가능성이 있음 이번에 처음 레디스를 사용하면서 직렬화 및 역직렬화를 공부했기 때문임
b. 잭슨 자체의 문제점.
—> 라이브러리가 오류의 원인일 가능성은 현저히 떨어짐.
2번 문제에 관한 선택지
java.io.Serializable
인터페이스를 구현해하는 조건을 충족하지 못했던 것을 알게됨.//buld.gradle
//자바 직렬화 및 역직렬화 문제 해결 패키지
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310'
implementation 'com.fasterxml.jackson.core:jackson-databind'
@Getter
@Entity
public class ChatMessage extends TimestampedChat implements Serializable {
private static final long serialVersionUID = 6494678977089006639L;
...
}
@Getter
@Setter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class TimestampedChat implements Serializable {
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@CreatedDate
private LocalDateTime createdAt;
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@LastModifiedDate
private LocalDateTime modifiedAt;
}
결과
정상적으로 레디스에 저장이 되었다.
정상적으로 시간을 포함한 이전 채팅기록이 출력되었다.
{
"statusCode": 200,
"msg": "OK",
"data": [
{
"createdAt": "2022-10-04T13:03:03.8935017",
"modifiedAt": "2022-10-04T13:03:03.8935017",
"id": 2,
"roomId": "f137251e-161a-43fd-9fbc-ac3068618354",
"roomName": "경매1번방",
"type": "TALK",
"sender": "위키미키",
"message": "ㅎㅇㅎㅇ",
"nickName": "위키미키",
"profileImgUrl": null,
"createdAtString": "2022-10-04 13:03:03"
},
{
"createdAt": "2022-10-04T13:03:05.1414266",
"modifiedAt": "2022-10-04T13:03:05.1414266",
"id": 3,
"roomId": "f137251e-161a-43fd-9fbc-ac3068618354",
"roomName": "경매1번방",
"type": "TALK",
"sender": "위키미키",
"message": "네넹",
"nickName": "위키미키",
"profileImgUrl": null,
"createdAtString": "2022-10-04 13:03:05"
},
{
"createdAt": "2022-10-04T13:03:06.0023846",
"modifiedAt": "2022-10-04T13:03:06.0023846",
"id": 4,
"roomId": "f137251e-161a-43fd-9fbc-ac3068618354",
"roomName": "경매1번방",
"type": "TALK",
"sender": "위키미키",
"message": "ㅎㅎ",
"nickName": "위키미키",
"profileImgUrl": null,
"createdAtString": "2022-10-04 13:03:06"
}
]
}
이 오류를 해결한 이후 멘토님이 조금더 redis를 공부해보라고 말씀하셨다.
직렬화 역직렬화시 serialVersionUID가 왜 필요한지 모르고 사용하면 안된다고 말씀하셨다.
redis를 사용하면 좋은 부분은 데이터가 자주 바뀌지 않으면서 조회해올 데이터가 용량이 클때 효과적이라고 말씀해 주셨다.
미처 이런 부분에서 사용할줄은 정말 몰랐고 앞으로 공부후에 따로 정리를 해두어야 겠다고 생각했다.