Grails finds a parent in many ways

My problem should be obvious, but I just don't see the light right now: - (

I have two such classes:

class Parent { String name static hasMany = [children: Child] } class Child { String name } 

Now I have to find the parent of the child using the dynamic parent finder, for example:

 Parent.findByChildren([someChild] as Set) 

But I get an error in sleep mode, stating that I have a grammar error in my hibernate SQL:

 Caused by: java.sql.SQLException: No value specified for parameter 1 

And for reference: someChild is a specific instance. And I would like to avoid Child in order to have an explicit parent in the definition.

How then can I go from Child to Parent?

Best wishes,

Christian Sonn Jensen

+4
source share
4 answers

To finish this question, I wanted to report a solution to my "problem." I use namedQuery in the parent object (Customer or Producer) as follows:

 Class Customer { static hasMany = [channels: Channel] static namedQueries = { findByChannel { channelId -> channels { eq 'id', channelId } } } } 

Then I find Customer as follows:

 def customers = Customer.findByChannel(channel.id).list() 

Thus, the Channel is freed from the burden of knowing something about who is referencing it, and I do not need to make any artificial link tables.

I still think it must be some kind of error, that I cannot use one of the dynamic searchers:

 Customer.findByChannels([channel] as Set) 

Perhaps dynamic crawlers do not take into account the one-to-many relationship and work only for simple attributes ??? (I am using Grails 1.3.1)

Thank you for your responses!

Christian Sonn Jensen

+2
source

If you do not need a parent foreign key for the child, you will have to create a connection table for the parent, which serves as a surrogate for the child:

 class ParentalRelationship { static belongsTo = [parent: Parent, child: Child] } 

You can then have helper methods for the parent to query for children through the ParentalRelationship object.

With your actual implementation of clients, channels and producers, it is likely that you will need a many-to-many relationship, since the channel will not belong to any client (or to one producer).

+1
source

Perhaps the best way is to write something like this in chield belongsTo :

 static belongsTo = [parent: Parent] 

And then you can use:

 Chield c = ... Parent parent = c.parent 
+1
source

I would invert it:

 class Parent { String name static Set<Child> getChildren() { Child.findAllByParent(this) as Set } } class Child { String name Parent parent } 

In this case, the same database structure is used (the child table has a foreign key for the parent), but facilitates the transition from one side to the other without being explicitly bidirectional.

One thing is changing. Instead of this:

 def parent = ... parent.addToChildren(new Child(...)) parent.save() 

do the following:

 def parent = ... def child = new Child(parent: parent, ...).save() 

This is more efficient because you do not need to load the entire collection just to save the new child.

0
source

Source: https://habr.com/ru/post/1314153/


All Articles