I’m working on a chat application using Spring Boot, and I’m facing an issue with managing chat messages when the chat reaches its maximum size. My goal is to implement a system where, once the maximum number of messages is reached, the oldest message is removed to make room for a new one. However, I’m encountering a problem where the new message seems to replace the first message in the list instead of being added to the end.
Here’s the relevant part of my ChatMessageServiceImpl
class:
@Service
@RequiredArgsConstructor
public class ChatMessageServiceImpl implements ChatMessageService {
private final ChatRepository chatRepository;
private final UserService userService;
@Value("${monopoly.app.chat.max-size}")
private Integer maxSize;
@Override
public ChatMessage save(Chat chat, ChatMessageDto chatMessageDto) {
ChatMessage chatMessage = ChatMessage.builder()
.sender(userService.findByUsername(chatMessageDto.getSender()))
.content(chatMessageDto.getContent())
.timestamp(LocalDateTime.now())
.receiver(chatMessageDto.getReceiver() != null ?
userService.findByUsername(chatMessageDto.getReceiver()) : null)
.chat(chat)
.build();
// Check if the chat has reached the max size
if (chat.getMessages().size() >= maxSize) {
chat.getMessages().remove(0); // Remove the first message
}
chat.getMessages().add(chatMessage); // Add the new message to the end
chatRepository.save(chat);
return chatMessage;
}
}
When the chat reaches the maximum size, the new message is supposed to be added to the end of the list, and the oldest message should be removed. Instead, it appears that the new message replaces the first message in the list.
Here’s Chat
class if you have questions about how messages are stored:
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Builder
@Entity
@Table(name = "chats")
public class Chat {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private Integer unreadMessages = 0;
@OneToMany(mappedBy = "chat", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
private List<ChatMessage> messages = new ArrayList<>();
}
-
I confirmed that the list of messages is a standard
List
and should support theremove
andadd
operations correctly. -
I tried explicitly creating a new list, copying the messages, and then updating the chat entity’s message list:
List<ChatMessage> messages = chat.getMessages();
if (messages.size() >= maxSize) {
messages.remove(0);
}
messages.add(chatMessage);
chat.setMessages(messages);
- I verified that the database correctly updates the
Chat
entity with the new list of messages.
What might be causing the new message to replace the first message instead of being added to the end? Are there any potential issues with how the list or the database is being handled in this situation?