Quantcast

GORM hasMany problems

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

GORM hasMany problems

Stephen Cresswell
I have two domain classes, Person and Message. I need to track who sends a message and also maintain a history of who receives a message.

class Message {
    String text
    Person sender
}

class Person {
    Set<Message> received = []   
    static hasMany = [recieved: Message]
}

When modelled as above, instead of creating a join table, 'person_message' GORM tries to re-use Message.sender, so that the underlying schema only has the following tables

PERSON (id, version)
MESSAGE (id, version, sender_id, text)

Calling person.addToReceived(message) actually updates the sender_id column, trashing who the sender really was. Without a join table it is not possible for many people to associated with the same message.
If I remove the sender property from the Message class, GORM creates the join table as you would expect, but then I have no way to track who sent the message.

Does anyone know how to get GORM to behave in this scenerio?

Cheers,

Steve

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

RE: GORM hasMany problems

Abhijit Sharma

In a lighter vein J I don’t think the subject is quite true – I don’t think GORM “hasMany” problems … probably a few J

 

Regards,

Abhijit


From: Stephen Cresswell [mailto:[hidden email]]
Sent: Friday, August 08, 2008 5:09 PM
To: [hidden email]
Subject: [grails-user] GORM hasMany problems

 

I have two domain classes, Person and Message. I need to track who sends a message and also maintain a history of who receives a message.

class Message {
    String text
    Person sender
}

class Person {
    Set<Message> received = []   
    static hasMany = [recieved: Message]
}

When modelled as above, instead of creating a join table, 'person_message' GORM tries to re-use Message.sender, so that the underlying schema only has the following tables

PERSON (id, version)
MESSAGE (id, version, sender_id, text)

Calling person.addToReceived(message) actually updates the sender_id column, trashing who the sender really was. Without a join table it is not possible for many people to associated with the same message.
If I remove the sender property from the Message class, GORM creates the join table as you would expect, but then I have no way to track who sent the message.

Does anyone know how to get GORM to behave in this scenerio?

Cheers,

Steve

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: GORM hasMany problems

Peter Ledbrook
In reply to this post by Stephen Cresswell
> I have two domain classes, Person and Message. I need to track who sends a
> message and also maintain a history of who receives a message.
>
> class Message {
>     String text
>     Person sender
> }
>
> class Person {
>     Set<Message> received = []
>     static hasMany = [recieved: Message]
> }
>
> When modelled as above, instead of creating a join table, 'person_message'
> GORM tries to re-use Message.sender, so that the underlying schema only has
> the following tables

You need to use a custom ORM mapping:

  class Person {
      Set<Message> received = []
      static hasMany = [received: Message]

      static mapping = {
          received joinTable:[name:'Person_Addresses',
key:'Person_Id', column:'Address_Id']
      }
  }

See section 5.5.2.1 of the use guide for more info. An alternative is
approach is to add a "recipient" field to Message and use the
"mappedBy" property described in section 5.2.1.2 of the user guide and
in the reference section.

Hope that helps,

Peter

--
Software Engineer
G2One, Inc.
http://www.g2one.com/

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: GORM hasMany problems

Jakob Külzer
In reply to this post by Stephen Cresswell
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi Stephen,
On 08.08.2008, at 13:38, Stephen Cresswell wrote:

> Calling person.addToReceived(message) actually updates the sender_id  
> column, trashing who the sender really was. Without a join table it  
> is not possible for many people to associated with the same message.


IMHO GORM thinks you want a bi-directional connection between person  
and message (that's what you usually want when you add properties in  
this constellation). Gorm offers mappedBy which you can use to specify  
by which property a collection is mapped (see http://grails.org/GORM+-+Defining+relationships 
  and search for mappedBy). However i do not know if you can enforce a  
uni-directional relationship with this. But you could add a
static hasMany = [ 'receivers':Person] to your Message class. That  
would be an m:m relationship which is rather ugly, personally i would  
introduce a third class between Person and Message. Hope that helps...

Cheers,
Jakob Külzer <[hidden email]>



-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (Darwin)

iD8DBQFInDjFo/rHbQ+SfLQRAvKhAKDPUU5FalHnHZL/UneFvhAWC4KsdgCgyJk5
rFCE29NXkLZ8CcT/t7TVPtU=
=/4qr
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: GORM hasMany problems

Stephen Cresswell
In reply to this post by Peter Ledbrook
Thanks for your help Peter, however specifying joinTable doesn't make the slightest bit of difference - GORM still doesn't create a join table

class Message {
    String text
    Human sender
}

class Person {
    Set<Message> received = []
    static hasMany = [received: Message]
    static mapping = {
        received joinTable:[name: 'person_messages', key: 'person_id', column: 'message_id']
    }
}

I don't see how mappedBy is relevant as I need the join table - without it I can't associate a message with many receipients.

Jakob's suggestion of using a many-to-many would work, but I was hoping to avoid this, since i don't need the relationship to be bi-directional. I'm starting to think the best solution is to model the received messages list as a new domain object, and not make it a property of either Person or Message.

Regards.


2008/8/8 Peter Ledbrook <[hidden email]>
> I have two domain classes, Person and Message. I need to track who sends a
> message and also maintain a history of who receives a message.
>
> class Message {
>     String text
>     Person sender
> }
>
> class Person {
>     Set<Message> received = []
>     static hasMany = [recieved: Message]
> }
>
> When modelled as above, instead of creating a join table, 'person_message'
> GORM tries to re-use Message.sender, so that the underlying schema only has
> the following tables

You need to use a custom ORM mapping:

 class Person {
     Set<Message> received = []
     static hasMany = [received: Message]

     static mapping = {
         received joinTable:[name:'Person_Addresses',
key:'Person_Id', column:'Address_Id']
     }
 }

See section 5.5.2.1 of the use guide for more info. An alternative is
approach is to add a "recipient" field to Message and use the
"mappedBy" property described in section 5.2.1.2 of the user guide and
in the reference section.

Hope that helps,

Peter

--
Software Engineer
G2One, Inc.
http://www.g2one.com/

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

   http://xircles.codehaus.org/manage_email



Loading...