In grails, I can implement an N:1 relationship like this:
class Parent { hasMany = [children:Child] }
class Child { belongsTo = [parent:Parent] }
Now (if addTo and removeFrom is always properly used) I can get a Parent's children via parent.children.
But I can also do it without hasMany:
class Parent { }
class Child { belongsTo = [parent:Parent] }
Then I have to use Child.findAllByParent(parent) to get all children.
My question: Are there any important reasons why I should use hasMany if can query a parent's children in the second way as well?
I guess that it's sometimes easier (and perhaps faster if eager-fetched together with the parent?) to just refer to parent.children, but on the other hand this List can become rather long when there are several children. And what I don't like about hasMany either is that you always have to take care about the addTo or removeFrom or to clear the session after adding a new Child with a Parent so that grails does this automatically...
Is the answer that you should simply use hasMany if there are few children and don't use it if there are many (for performance reasons), or is there more behind it?
You are doing user. addToReponse(q) instead it should be user. addToReponse(questionnaire) , if it's not a typo and the data is actually not being stored, then check by adding the failOnError parameter to save() method. Sometimes grails save() method fails silently, it should tell you if this is the case.
A domain class fulfills the M in the Model View Controller (MVC) pattern and represents a persistent entity that is mapped onto an underlying database table. In Grails a domain is a class that lives in the grails-app/domain directory.
GORM is the data access toolkit used by Grails and provides a rich set of APIs for accessing relational and non-relational data including implementations for Hibernate (SQL), MongoDB, Neo4j, Cassandra, an in-memory ConcurrentHashMap for testing and an automatic GraphQL schema generator.
Using hasMany versus belongsTo is more related to the cascading behavior you want to specify when an update/delete occurs. In your second example, the cascading is set to ALL on the children side and NONE on the parent side. If you delete a child, nothing will happen on the parent. If you delete the parent, all the children will automatically be deleted.
In your first example cascading is set to ALL on the parent side, and SAVE-UPDATE on the child side. So now you can do something like:
parent.addToChildren(child1)
parent.addToChildren(child2)
parent.addToChildren(child3)
parent.save(flush:true)
And when you save the parent, all the children will be updated.
Touching on something you didn't ask, you could also presumably have something like:
class Parent { hasMany = [children:Child] }
class Child { Parent parent }
If you define the relationship from Child to Parent in this way, you will need to manually manage the Child objects that reference the parent when you delete the parent*. (*this corrects a previous statement that proved to be inaccurate)
So, the hasMany/belongsTo has two main considerations:
UPDATE:
I also want to clarify, GORM will not eager-fetch when you use hasMany; by default GORM uses a lazy fetch strategy so it won't get the children until attempt to access parent.children
If you want an association to be eagerly fetched by default, you can specify the appropriate mapping:
class Parent {
hasMany = [children:Child]
static mapping = {
children lazy:false
}
}
Finally, you mentioned that you don't like that you have to worry about the addTo/removeFrom on the hasMany side. You shouldn't have to do this if you save with flush:true.
def parent = Parent.get(id)
def child = new Child(name:'child1', parent:parent)
if(child.save(flush:true)) {
// both sides of the relationship should be good now
}
EDIT: fixed reversed order of child/parent cascade defaults and corrected misconception regarding how gorm handled relationships without belongsTo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With