views:

25

answers:

3

Hi,

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

I have two domainclasses like this:

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

class Child {
  String name
}

Now I should be able to find the Parent of a child by using the dynamic finder of the Parent like:

Parent.findByChildren([someChild] as Set)

But I get a hibernate error stating that I've got a grammar error in my hibernate SQL:

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

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

How then can I go from the Child to the Parent?

Best Regards,

Christian Sonne Jensen

A: 

I would invert it:

class Parent {
  String name

  static Set<Child> getChildren() {
    Child.findAllByParent(this) as Set
  }
}

class Child {
  String name
  Parent parent
}

This uses the same database structure (the child table has a foreign key to parent) but makes it easy to go from one side to the other without being explicitly bidirectional.

One thing does change. Instead of this:

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

you do this:

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

This is more performant because you don't need to load the entire collection just to persist a new child.

Burt Beckwith
Yeah, I was thinking along those lines, but I want to avoid that the Child knows about its parent. In my REAL case I have a Customer and a Channel as Parent and Child. The Customer has a list of Channels, but a Channel could also be mapped by eg a Producer. Therefore the Channel should not know about the Customer (or Producer), as that would make the Channel less general. It is a common fenomenon to have tables mapped by other entities without the tables knowing about it. I just need to know the syntax for going from a Child (Channel) to af Parent (Customer/Producer/Whatever) Best Regards
+1  A: 

If you don't want the parent foreign key on the child, you'll have to create a join table for the parent that serves as a surrogate for the child:

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

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

With your real implementation of Customers, Channels, and Producers, chances are that you'd want a many-to-many relationship anyways as a channel wouldn't belong to a single customer (or a single producer).

Ted Naleid
+1  A: 

Hi,

Just to end this question, I wanted to report a solution to my "problem". I'm using a namedQuery in the Parent entity (Customer or Producer) like this:

Class Customer {

  static hasMany = [channels: Channel]

  static namedQueries = {
   findByChannel {
        channelId ->
          channels {
              eq 'id', channelId
      }
    }
  }
}

Then I find the Customer like this:

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

In this way the Channel are relieved of the burden of knowing anything about who references it, and I don't have to do any artificial relationship tables.

I still think that it must be some kind of mistake that I cannot use one of the dynamic finders:

Customer.findByChannels([channel] as Set)

Maybe the dynamic finders doesn't take one-to-many relationsships into account, and only works for simple attributes??? (I'm using Grails 1.3.1)

Thanks for your replies though!

Christian Sonne Jensen