Rodrigo Mocca
Rodrigo Mocca

Reputation: 11

Grails: Simple hasMany relation create more tables than necessary

Hi I have a simple problem. My domain class is like this:

class Example {

    long seq

    hasMany = [example_array: ExampleData]

    long count
}

class ExampleData {

    String type

    long description

    static belongsTo = Example

    static constraints = {
    }
}

This results in 3 tables, like a many to many relation. Why is this?

Thanks

Upvotes: 0

Views: 797

Answers (4)

Prakash Thete
Prakash Thete

Reputation: 3892

Well the one-to-many relationship is constructed by having additional table (i.e. Example_ExampleData) containing two columns each id fields from tables of the entities forming the relationship(i.e. Example and ExampleData).

The newly added table is child to parent tables – Example and ExampleData.

So in your case when you run your application the 3rd table gets created by Grails by default as your table relationship falls under the one-to-many relationship.

Upvotes: 0

Burt Beckwith
Burt Beckwith

Reputation: 75671

The reason for the extra table is that you've modeled the relation only in one direction - an Example can access its ExampleData instances via the example_array Set that's added to your class bytecode because of the hasMany property, but an ExampleData instance has no way to reference its owning Example.

You added a belongsTo property, but only specified the class name. That's sufficient to configure ownership, cascaded deletes, etc. but doesn't provide a property in the class to access the Example instance.

If you change it to the other supported syntax it will work as you expected:

static belongsTo = [example: Example]

Here example will end up being the name of an Example property (and you can change it and/or example_array to any valid property name), which is basically the same as declaring

Example example

Now that both sides can access the other, the relationship is bidirectional and you no longer need the third table. That's because a 1-many is typically implemented using a foreign key in the child table, in this case in the table for ExampleData that points to the table for Example. That wasn't possible without a property in the class to wire up to that column, so the join table was necessary.

Upvotes: 1

Sayem
Sayem

Reputation: 713

From the definition of hasMany Grails will, by default, map this kind of relationship with a join table.That join table is the 3rd table you mentioned.No need to worry about that.

Upvotes: 0

deniscapp
deniscapp

Reputation: 820

I believe that you have to map the BelongsTo, like this:

static belongsTo = [example:Example]

Hope it helps :)

Upvotes: 0

Related Questions