What is the difference between mappedBy and belongsTo for m-m relationships? - grails

What is the difference between mappedBy and belongsTo for m-m relationships in Grails? How can the two be used in a same Domain?

I think there are 3 with 1 that has two formats:
There is belongsTo:
belongsTo=[something:Something] and belongsTo=Something or belongsTo=[Something,Another]
There is Something something
and finally hasOne=[something:Something]
When you declare Something something this actually creates a table cell called something_id
When you declare belongsTo=[something:Something] something_id isn't created and I think if I understand correctly that relationship is now managed by hibernate.
Points of reference Explain belongsTo in Grails and Grails hasOne vs. belongsTo
So in short one you manage the relationship through db and other is managed by hibernate.
How can the two be used in the same domain ?
Why would you need both if they are both pointing to the same parent ?
You can use either method for any relationship the belongsTo is a hibernate control mechanism telling it what / which way the relationship is so therefore the Parent must have Child child mapping
Where as Something something or Parent parent really has none of the above requirements. Hope it is making sense

Related

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
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.
I believe that you have to map the BelongsTo, like this:
static belongsTo = [example:Example]
Hope it helps :)
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.
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.

Is there any difference between "belongsTo" constraint and just being a field in Grails?

I have created Child domain and made 2 parents to it. One parent I declared as a field. And another parent I declared with the help of belongsTo constraint.
package multipleparentsgrails
class Child {
Parent2 parent2
static belongsTo = [parent1: Parent1]
static constraints = {
}
}
Is there any difference between these ways?
How to eliminate differences? Can I have both belongTo and a member? Can I add cascading having a member?
belongsTo plays significant role in parent child relationship. Here the class specified in belongsTo is the Parent / Owner of the relationship.
Following could be some comparison in normal has a and belongs To:
belongsTo marks the referenced class as Owner of the relationship while same is not true in case of has a
You don't need to worry about hibernate related cascading as relationship automatically will handle that i.e. you may specify cascade type but need not to give implementations otherwise in case of has a you have to use GORM DSL like stuff.
Last but not least belongsTo also makes it mandatory to specify relationship owner while in case of has a constraints are the barriers.
Last but not least it might also make difference in gsp scaffolding as well but not sure about it.
Hope it Helps!
Yes, belongsTo defines cascading. If parent1 is deleted, so is child since it belongsTo parent1. If parent2 is deleted, Grails won't delete child automatically for you.
So, in this case, stating that a child belongsTo a parent wouldn't be very children-friendly :-)
You can define belongsTo in a few different ways, which allows you to define it on separate fields or to declare new fields. See the Grails documentation for further details, they have good examples of its use.

Grails domain classes static properties hasOne, hasMany and belongsTo

I am new to Grails and I would like to know what impacts exist on generated code, db schema, GORM, etc. when using Grails' predefined static properties on domain classes like hasOne, hasMany and belongsTo.
For example, would hasOne force a singleton pattern somewhere?
Taking a quick look at both generated code and database, I didn't find many clues.
belongsTo forces a save of the child class when saving the parent class
hasOne creates a one-to-one / one-to-many mapping in the DB (no association table)
hasMany is used for one-to-many (is in one of the classes) / many-to-many (if in both classes, with association table)

One-to-many relationship not working as expected

I'm having some problems getting a one to many relationship in grails working properly.
I have a person instance and this person has relationships to other persons. This relationship is defined in a relationship object.
The relevant code is as follows.
class Person {
static hasMany = [relationships:Relationship]
String name
}
class Relationship {
Person relationShipTo
// Enum containing married, living together, parent etc.
RelationshipType typeOfRelationship
}
Now what i want is a one to many reference to that relationship to be persisted but what happens in grails is that it seems to think the relationShipTo instance is refering back to the Person that has this relationship with someone else, and not to the other person.
So a person has a reference to a relationship, and that relationship has a type and a reference to the person with whom you have a relationship with.
I'm not able to change the domain model for this. Is there any way of accomplishing what i want?
What is currently happening if i use the generated views and controllers for the Relationship and try to create a relationship with a type and a person it is refering to, only the type is persisted and the person is ignored. When i then try to add it to the person in the persons edit or create page, all the relationShipTo properties of the relationships i add is saved with the id of the person.
Hopefully what i wrote is understandable.
Finally got it working.
Had to add a static mappedBy =[relationship: 'belongsTo'] to person
and a static belongsTo = [belongsTo: Person].
Not exactly how i wanted it but it works and is an ok compromise

Grails: Collection in domain object without hasMany

I have two domain objects A and B.
A can be associated with many Bs but I do not want any save cascade from A to B.
I'm thinking of defining the hasMany relationship form A to B, but then setting a cascade behavior. Any ideas?
This is an example of my domain objects:
class A{
static hasMany = [bees:B]
}
class B{
}
If you do not wish for GORM to manage the save/updates for your collection simply don't use hasMany. Instead treat it as a simple HashSet property.
Why not use 'belongsTo' on B, and don't declare anything on A? This way you'll get the foreign key to 'A', but operations on 'A' won't affect 'B'. You lose a bit of convenience, but can still easily look up all 'B' by 'A'. I actually prefer this because I don't need to worry about lazy loading gotchas and hibernate going and loading all the 'B's when I'm just trying to add one (assuming you don't need that functionality).
class A{}
class B{
static belongsTo = [your_a:A]
}
//get your B's for a given A
B.findAllByA(your_A_instance, ...paging, etc...)
You can define your own cascading behavior in the static mappings block of your Domain class.
See here: http://grails.org/doc/latest/ref/Database%20Mapping/cascade.html
If you are saying what I think your are saying then what you are talking about is not cascading. A simple outline of your classes would be helpful. If you have an instance of A which is associated with many instances of B, then all instance of B which reference the instance of A in question are referencing the exact same object. I had the same problem and asked a similar question here. Basically your options are:
1.) Clone the instance of A whenever it changes or whenever you deem appropriate.
2.) Create new fields in your B class which will hold the values of A you are concerned with.
Both approaches have their advantages and disadvantages, but for me option 2 proved to be the better choice.

Resources