Grails

GORM: Unable to create a Many-to-Many with self if self has One-to-Many with self

Details

  • Type: Sub-task Sub-task
  • Status: Closed Closed
  • Priority: Critical Critical
  • Resolution: Fixed
  • Affects Version/s: 1.0.3
  • Fix Version/s: 1.1-beta3
  • Component/s: Persistence
  • Labels:
    None

Description

as mentioned here:
http://www.nabble.com/many-to-many-relationship-between-a-tree-and-itself--td18197066.html#a18197066

For example:

class Organization {
    //static def belongsTo = [Organization]
    static hasMany = [children: Organization, relatedOrganizations: Organization]
    //static mappedBy = [children: "parent", relatedOrganizations:"relatedOrganizations"]

    Organization parent
    String name
}

Without the parent/children tree relation, the many-to-many with self creates a separate organization_organization table as expected for relatedOrganizations. But with it, it doesn't. Instead it duplicates the one-to-many; relatedOrganizations = children.

I tried adding

static mappedBy = [children: "parent", relatedOrganizations:"relatedOrganizations"]

But that generates another unresolvable (circular) problem.
An error is thrown saying:

No owner defined between domain classes [Organization] and [Organization] in a many-to-many relationship.

If I add belongsTo = [Organization], I get this error:

Domain classes [Organization] and [Organization] cannot own each other in a many-to-many relationship. Both contain belongsTo definitions that reference each other.

Activity

Hide
Steve Tekell added a comment -

here's an example of demonstrating the problem of trying to have both a one-to-many and many-to-many with self.
It's like the class above, Organization, with some test data loaded in the bootstrap.
Although you'll have to comment out the mappedBy (and belongsTo) to get that far.

Show
Steve Tekell added a comment - here's an example of demonstrating the problem of trying to have both a one-to-many and many-to-many with self. It's like the class above, Organization, with some test data loaded in the bootstrap. Although you'll have to comment out the mappedBy (and belongsTo) to get that far.
Hide
Yuriy Zubarev added a comment -

It's rather a show-stopper issue for us. Any work-around?

Show
Yuriy Zubarev added a comment - It's rather a show-stopper issue for us. Any work-around?
Hide
Steve Tekell added a comment -

One workaround is to avoid many-to-many relationships altogether by using intermediate join classes. So in the above example I created a class like

class OrganizationLink {
Organization organization
Organization relatedOrganization
}

Then I added a getter in Organization, getRelatedOrganizations(), so that organization.relatedOrganizations gives you what it would in the many-to-many.

Show
Steve Tekell added a comment - One workaround is to avoid many-to-many relationships altogether by using intermediate join classes. So in the above example I created a class like class OrganizationLink { Organization organization Organization relatedOrganization } Then I added a getter in Organization, getRelatedOrganizations(), so that organization.relatedOrganizations gives you what it would in the many-to-many.
Hide
Graeme Rocher added a comment -

Moving to 1.1, problem is there is no way currently to specify a belongsTo with an association name. Well actually there is with:

static belongsTo = [foos:Bar]

But its not taken into account and this is quite a big change. We'll see if we can get it done for 1.1

Show
Graeme Rocher added a comment - Moving to 1.1, problem is there is no way currently to specify a belongsTo with an association name. Well actually there is with:
static belongsTo = [foos:Bar]
But its not taken into account and this is quite a big change. We'll see if we can get it done for 1.1
Hide
Graeme Rocher added a comment -

This now maps successfully with:

class Organization {
    static hasMany = [children: Organization, relatedOrganizations: Organization]
    static mappedBy = [children: "parent", relatedOrganizations:"relatedOrganizations"]

    Organization parent
    String name

    static constraints = {
        parent nullable:true
    }
}
Show
Graeme Rocher added a comment - This now maps successfully with:
class Organization {
    static hasMany = [children: Organization, relatedOrganizations: Organization]
    static mappedBy = [children: "parent", relatedOrganizations:"relatedOrganizations"]

    Organization parent
    String name

    static constraints = {
        parent nullable:true
    }
}
Hide
Fran García added a comment -

What happens if you have something like this?

def organization = Organization.get(1)

organization.addToRelatedOrganization(new Organization(name:'New organization'))
//Suppose the new organization has the ID number 2
organization.save()

I've an application very similar and it inserts in the table organization_organization two rows like these:

1
2 1

But i'd like that just insert one part of the relation, so | 1 | 2 |. Is it posible with GORM?

Show
Fran García added a comment - What happens if you have something like this? def organization = Organization.get(1) organization.addToRelatedOrganization(new Organization(name:'New organization')) //Suppose the new organization has the ID number 2 organization.save() I've an application very similar and it inserts in the table organization_organization two rows like these:
1
2 1
But i'd like that just insert one part of the relation, so | 1 | 2 |. Is it posible with GORM?
Hide
Graeme Rocher added a comment -

Bulk closing bunch of resolved issues

Show
Graeme Rocher added a comment - Bulk closing bunch of resolved issues

People

Vote (2)
Watch (3)

Dates

  • Created:
    Updated:
    Resolved: