Many to many mapping

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Many to many mapping

Chache Schulz
Hello.

I am trying to map a many-to-many relationship in glorp.

I have a class named 'User' and a class named 'Group'. These class have two relationships, the first one is one-to-may and expresses the 'owner' feature, and the other is many-to-many and expresses which user belong to which group, in other words, an user belongs to many groups and a groups contains many users.

My problem is when I try to map the many-to-many relationship, reading some tutorials I figure out that I need to specify the association table, but I tried many ways to do that without success...

The code generate the database successfully, also the one-to-many relationship, but when I try to add a member to a group, does not throw any exception, only a log error in Posgres Admin "Se encontro fin de archivo inesperado en la conexion del cliente", something like it found an unexpected end of file was found in the client connection.

Sorry for the bad english.

My code is the following.

classModelForGroup: aClassModel

aClassModel newAttributeNamed: #id.
aClassModel newAttributeNamed: #name

classModelForUser: aClassModel

aClassModel newAttributeNamed: #id.
aClassModel newAttributeNamed: #username.
aClassModel newAttributeNamed: #password.
aClassModel newAttributeNamed: #tweets collectionOf: TwittAR.Tweet.
aClassModel newAttributeNamed: #groups collectionOf: TwittAR.Group.
aClassModel newAttributeNamed: #groupsIbelong collectionOf: TwittAR.Group

descriptorForGroup: aDescriptor

| table linkTable |
self tableNamed: 'GROUP_HAS_USER'.
linkTable := self tableNamed: 'GROUP_HAS_USER'.
table := self tableNamed: 'GROUPS'.
aDescriptor table: table.
(aDescriptor newMapping: Glorp.DirectMapping) from: #id to: (table fieldNamed: 'id').
(aDescriptor newMapping: Glorp.DirectMapping) from: #name to: (table fieldNamed: 'name').
(aDescriptor newMapping: Glorp.ManyToManyMapping)
attributeName: #members;
referenceClass: TwittAR.User;
mappingCriteria: (Glorp.Join
    from: (table fieldNamed: 'id')
    to: (linkTable fieldNamed: 'group_id')).
(aDescriptor newMapping: Glorp.ManyToManyMapping)
attributeName: #tweets;
referenceClass: TwittAR.Tweet

descriptorForUser: aDescriptor

| table linkTable |
table := self tableNamed: 'USERS'.
linkTable:= self tableNamed: 'GROUP_HAS_USER'.
aDescriptor table: table.
(aDescriptor newMapping: Glorp.DirectMapping) from: #id to: (table fieldNamed: 'id').
(aDescriptor newMapping: Glorp.DirectMapping) from: #username to: (table fieldNamed: 'username').
(aDescriptor newMapping: Glorp.DirectMapping) from: #password to: (table fieldNamed: 'password').
(aDescriptor newMapping: Glorp.OneToManyMapping) attributeName: #tweets.
(aDescriptor newMapping: Glorp.OneToManyMapping) attributeName: #groups.

(aDescriptor newMapping: Glorp.ManyToManyMapping)
attributeName: #groupsIbelong;
referenceClass: TwittAR.Group;
mappingCriteria: (Glorp.Join
    from: (table fieldNamed: 'id')
    to: (linkTable fieldNamed: 'user_id')).

tableForGROUPS: aTable

| owner |
(aTable createFieldNamed: 'id' type: platform sequence) bePrimaryKey.
aTable createFieldNamed: 'name' type: platform text.
owner := aTable createFieldNamed: 'user_id' type: platform int4.
aTable addForeignKeyFrom: owner to: ((self tableNamed: 'USERS') fieldNamed: 'id').

tableForUSERS: aTable

(aTable createFieldNamed: 'id' type: platform sequence) bePrimaryKey.
aTable createFieldNamed: 'username' type: platform text.
aTable createFieldNamed: 'password' type: platform text

tableForGROUP_HAS_USER: aTable

| groupKey userKey |
"(aTable createFieldNamed: 'id' type: platform sequence) bePrimaryKey."
userKey := aTable createFieldNamed: 'user_id' type: platform int4.
aTable addForeignKeyFrom: userKey to: ((self tableNamed: 'USERS') fieldNamed: 'id').
groupKey := aTable createFieldNamed: 'group_id' type: platform int4.
aTable addForeignKeyFrom: groupKey to: ((self tableNamed: 'GROUPS') fieldNamed: 'id'


Thank you very much!

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To view this discussion on the web visit https://groups.google.com/d/msg/glorp-group/-/RICTnTZts_sJ.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/glorp-group?hl=en.
Reply | Threaded
Open this post in threaded view
|

Re: Many to many mapping

Alan Knight-2
That doesn't look too bad from a quick look. I would suggest
  - In the foreign keys for user and group, make them foreign keys to
the link table, not to the ultimate destination.
  - Remove the explicit Joins in the many-to-many relationships. If
the foreign keys are right and unambiguous it should figure them out
automatically, which is less error prone.
  - Turn on logging SQL and see what SQL is being sent. That, and the
stack, will probably give a much better indication of what's going
wrong than the database error message.

Alan

On Mon, Aug 13, 2012 at 8:00 AM, Chache Schulz <[hidden email]> wrote:

> Hello.
>
> I am trying to map a many-to-many relationship in glorp.
>
> I have a class named 'User' and a class named 'Group'. These class have two
> relationships, the first one is one-to-may and expresses the 'owner'
> feature, and the other is many-to-many and expresses which user belong to
> which group, in other words, an user belongs to many groups and a groups
> contains many users.
>
> My problem is when I try to map the many-to-many relationship, reading some
> tutorials I figure out that I need to specify the association table, but I
> tried many ways to do that without success...
>
> The code generate the database successfully, also the one-to-many
> relationship, but when I try to add a member to a group, does not throw any
> exception, only a log error in Posgres Admin "Se encontro fin de archivo
> inesperado en la conexion del cliente", something like it found an
> unexpected end of file was found in the client connection.
>
> Sorry for the bad english.
>
> My code is the following.
>
> classModelForGroup: aClassModel
>
> aClassModel newAttributeNamed: #id.
> aClassModel newAttributeNamed: #name
>
> classModelForUser: aClassModel
>
> aClassModel newAttributeNamed: #id.
> aClassModel newAttributeNamed: #username.
> aClassModel newAttributeNamed: #password.
> aClassModel newAttributeNamed: #tweets collectionOf: TwittAR.Tweet.
> aClassModel newAttributeNamed: #groups collectionOf: TwittAR.Group.
> aClassModel newAttributeNamed: #groupsIbelong collectionOf: TwittAR.Group
>
> descriptorForGroup: aDescriptor
>
> | table linkTable |
> self tableNamed: 'GROUP_HAS_USER'.
> linkTable := self tableNamed: 'GROUP_HAS_USER'.
> table := self tableNamed: 'GROUPS'.
> aDescriptor table: table.
> (aDescriptor newMapping: Glorp.DirectMapping) from: #id to: (table
> fieldNamed: 'id').
> (aDescriptor newMapping: Glorp.DirectMapping) from: #name to: (table
> fieldNamed: 'name').
> (aDescriptor newMapping: Glorp.ManyToManyMapping)
> attributeName: #members;
> referenceClass: TwittAR.User;
> mappingCriteria: (Glorp.Join
>     from: (table fieldNamed: 'id')
>     to: (linkTable fieldNamed: 'group_id')).
> (aDescriptor newMapping: Glorp.ManyToManyMapping)
> attributeName: #tweets;
> referenceClass: TwittAR.Tweet
>
> descriptorForUser: aDescriptor
>
> | table linkTable |
> table := self tableNamed: 'USERS'.
> linkTable:= self tableNamed: 'GROUP_HAS_USER'.
> aDescriptor table: table.
> (aDescriptor newMapping: Glorp.DirectMapping) from: #id to: (table
> fieldNamed: 'id').
> (aDescriptor newMapping: Glorp.DirectMapping) from: #username to: (table
> fieldNamed: 'username').
> (aDescriptor newMapping: Glorp.DirectMapping) from: #password to: (table
> fieldNamed: 'password').
> (aDescriptor newMapping: Glorp.OneToManyMapping) attributeName: #tweets.
> (aDescriptor newMapping: Glorp.OneToManyMapping) attributeName: #groups.
>
> (aDescriptor newMapping: Glorp.ManyToManyMapping)
> attributeName: #groupsIbelong;
> referenceClass: TwittAR.Group;
> mappingCriteria: (Glorp.Join
>     from: (table fieldNamed: 'id')
>     to: (linkTable fieldNamed: 'user_id')).
>
> tableForGROUPS: aTable
>
> | owner |
> (aTable createFieldNamed: 'id' type: platform sequence) bePrimaryKey.
> aTable createFieldNamed: 'name' type: platform text.
> owner := aTable createFieldNamed: 'user_id' type: platform int4.
> aTable addForeignKeyFrom: owner to: ((self tableNamed: 'USERS') fieldNamed:
> 'id').
>
> tableForUSERS: aTable
>
> (aTable createFieldNamed: 'id' type: platform sequence) bePrimaryKey.
> aTable createFieldNamed: 'username' type: platform text.
> aTable createFieldNamed: 'password' type: platform text
>
> tableForGROUP_HAS_USER: aTable
>
> | groupKey userKey |
> "(aTable createFieldNamed: 'id' type: platform sequence) bePrimaryKey."
> userKey := aTable createFieldNamed: 'user_id' type: platform int4.
> aTable addForeignKeyFrom: userKey to: ((self tableNamed: 'USERS')
> fieldNamed: 'id').
> groupKey := aTable createFieldNamed: 'group_id' type: platform int4.
> aTable addForeignKeyFrom: groupKey to: ((self tableNamed: 'GROUPS')
> fieldNamed: 'id'
>
>
> Thank you very much!
>
> --
> You received this message because you are subscribed to the Google Groups
> "glorp-group" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/glorp-group/-/RICTnTZts_sJ.
> To post to this group, send email to [hidden email].
> To unsubscribe from this group, send email to
> [hidden email].
> For more options, visit this group at
> http://groups.google.com/group/glorp-group?hl=en.

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/glorp-group?hl=en.

Reply | Threaded
Open this post in threaded view
|

Re: Many to many mapping

Chache Schulz
In reply to this post by Chache Schulz

Thank you for your answer Alan!

I will consider your suggestions!

What is the best way to map many to many relationship? I can not figure out how to specify the association table...

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To view this discussion on the web visit https://groups.google.com/d/msg/glorp-group/-/FohLAc6AgZIJ.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/glorp-group?hl=en.
Reply | Threaded
Open this post in threaded view
|

Re: Many to many mapping

Alan Knight-2
Well, the easiest way is that if you have the table mappings and the
foreign keys set up you should only need to specify the type of
relationship, the fact that it uses a link table and the name of the
attribute and it should figure it out for you. If it knows that ClassA
maps to TableA and ClassB maps to TableB and that association table
LINK has a foreign key to TableA and to TableB and is the only one
that does, then that's enough information. Since ManyToMany defaults
to using a link table, that's automatic. If there are things that are
ambiguous or unspecified, then you need to add more information.

The easiest way to find examples is to look at the tests and find uses
of ManyToManyMapping, or just ToManyMapping.

On Mon, Aug 13, 2012 at 11:52 AM, Chache Schulz <[hidden email]> wrote:

>
> Thank you for your answer Alan!
>
> I will consider your suggestions!
>
> What is the best way to map many to many relationship? I can not figure out
> how to specify the association table...
>
> --
> You received this message because you are subscribed to the Google Groups
> "glorp-group" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/glorp-group/-/FohLAc6AgZIJ.
>
> To post to this group, send email to [hidden email].
> To unsubscribe from this group, send email to
> [hidden email].
> For more options, visit this group at
> http://groups.google.com/group/glorp-group?hl=en.

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/glorp-group?hl=en.

Reply | Threaded
Open this post in threaded view
|

Re: Many to many mapping

Chache Schulz
In reply to this post by Chache Schulz
Where can I find tests in VW 7.8 with the last version of glorp??

--
You received this message because you are subscribed to the Google Groups "glorp-group" group.
To view this discussion on the web visit https://groups.google.com/d/msg/glorp-group/-/GyEEq5K1kSYJ.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/glorp-group?hl=en.