1

I am implementing a simple chat system in Grails as part of an existing application.

The main classes to consider are:

User.groovy

class User {

    ...

static hasMany = [
    ...
    chatMessages : ChatMessage,
    conversationParticipations:ConversationParticipation
    ]


static constraints = {
    ...     
}

}

ChatConversation.groovy

class ChatConversation {

static hasMany = [
    conversationParticipations:ConversationParticipation,
    chatMessages:ChatMessage
    ]

static constraints = {
}
}

ConversationParticipation.groovy - the intermediate class to remove the many-many between User and ChatConversation

class ConversationParticipation {

ChatMessageBuffer chatMessageBuffer

static constraints = {
    chatMessageBuffer nullable : true
}


static belongsTo = [
    user:User,
    chatConversation:ChatConversation       
    ]

}

ChatMessageBuffer.groovy - used to hold chat messages, not yet read by a Conversation Participant

class ChatMessageBuffer {

static hasMany = [
    chatMessages : ChatMessage
    ]

static belongsTo = [
    conversationParticipation:ConversationParticipation
    ]

static constraints = {
    chatMessages nullable : true
    conversationParticipation nullable : true
}

}

In a service I am calling methods to create a conversation and then to send any sent messages to the ChatMessageBuffers for that conversation like this

def createChatConversation(chatDetails)
{
    def chatConversation = new ChatConversation()


    chatConversation.save(flush:true, failOnError:true)


    new ConversationParticipation(
        user:getCurrentUser(),
        chatConversation:chatConversation,
        chatMessageBuffer:new ChatMessageBuffer()
    ).save(flush:true, failOnError:true)

    new ConversationParticipation(
        user:User.get(chatDetails.id),
        chatConversation:chatConversation,
        chatMessageBuffer: new ChatMessageBuffer()
    ).save(flush:true, failOnError:true)

    return chatConversation     
}

def sendMessage(chatMessageDetails)
{
    //save the message
    def chatMessage = new ChatMessage(
            body:chatMessageDetails.chatMessage,
            dateSent: new Date(),
            user:getCurrentUser(),
            chatConversation:ChatConversation.get(chatMessageDetails.chatConversationId)
        ).save(flush:true,failOnError : true)   

    //add the message to the message buffer for each participant of the conversation.   
    ConversationParticipation.findAllByChatConversation(            
        ChatConversation.get(chatMessageDetails.chatConversationId)
        ).each {                
            if(it.chatMessageBuffer.addToChatMessages(chatMessage).save(flush:true, failOnError:true))
            {
                println"adding to ${it.chatMessageBuffer.id}"
                println"added to : ${it.chatMessageBuffer.dump()}"                  
            }               
        }



        def chatMessageBuffer = ChatMessageBuffer.get(1)

        println"service : message buffer ${chatMessageBuffer.id}: ${chatMessageBuffer.dump()}"


    return chatMessage
}

As you can see on creating a ConversationParticipation object, I am also creating a ChatMessageBuffer, which is cascading save when I call save on the new ConversationParticipation.

My problem is when I am adding the ChatMessages to the two ChatMessageBuffers, the first ChatMessageBuffer is not saving, but the second is. So when I go to add another ChatMessage to the same buffers, the first buffer is empty, but the second buffer contains the previously added ChatMessage(s).

Does anybody have any idea where I am going wrong? Why the first one will not save/update?

4

0 回答 0