Question

I have two domain classes in which one has a one to many relationship with the other

Class A
{
   ...
   @NotNull
   static hasMany = [bElements:B]
}

Class B
{
   ...
}

When I run the application, the relation table A_B is created and entries in A_B table are automatically added when user creates A objects. Then I've decided to change this relation, because I've noticed that it is better to have a relation between class A and class C, so class A now has

static hasMany = [cElements:C]

but when I create a new object of type A (after creation of some C objects), adding one or more objects of type C, in my database I don't see the entry into the A_C table, but only in A table.

Why do this beahavior happens? What must I control to resolve problem?

EDIT: maybe it is needed some clarifications. The Class A is a class that describes an invoice and the class C is a class that describes the invoices items. So I need to give a one-to-many relationship between this two classes, but as described above, it does not work as expected...

EDIT 2: I've noticed that maybe the problem depends on the fact that the field cElements in A object is null. In the view, I've described the cElements field as follows:

<g:select name="receiptItems" from="${HealthService.findAllByDoctor(Doctor.findBySecUser(new ReceiptController().getCurrentlyLoggedUser()))}"
              multiple="multiple" optionKey="id"
              optionValue="${{it.healthServiceType.healthService}}"
              size="5" value="${receiptInstance?.healthServices*.id}" class="many-to-many"
              onchange="${remoteFunction(
                      controller: 'Receipt',
                      action: 'sumReceiptItems',
                      params: '\'receiptItemsSelected=\' + jQuery(this).val()',
                      onSuccess: 'updateTotalAmount(\'totalAmount\', data, \'00000\')')}"/>

It is a multiple select. After each selection, with the remoteFunction, a method from controller is called to do some calculation and update the totalAmount field. It works well but, when save method is called, healthServices field is null...and I don't understand why...I will open another post to solve this issue (solved here)

Était-ce utile?

La solution

If you declare a class like

Class A
{
   ...
   @NotNull
   static hasMany = [cElements:C]
}

Class C
{
static belongsTo= [a:A]
   ...
}

In this case it does not create A_C but if you declare it like

Class A
{
   ...
   @NotNull
   static hasMany = [cElements:C]
}

Class C
{
//no belongTo
   ...
}

then it creates A_C in database to map these fields id.

Autres conseils

There is no need to have an intermediate table with A-B relations when you have one-to-many relation esablished. If relation was bidirectional (B class objects could have multiple A class objects) then the intermediate table would be useful.

Check your databse whether your B class objects contain pointers (foreign keys) to A class objects. If they do, your ORM decided to create one-to-many relationship and your A-B relations table is not used.

I would ditch the intermediate table for now and add the following to B class static belongsTo = [parent:A] (keep the hasMany in A):

This will create a bi-directional relationship from B to A (aka foreign key in B table). Make sure you are conscious of how cascading deletes are handled with belongsTo. http://grails.org/doc/2.2.x/ref/Domain%20Classes/belongsTo.html

You mentioned pre-populating. Make sure you aren't violating any constraints. Bootstrap often fails silently. Add something like on your instance in question: ` if (!b.save()) { b.errors.each { println it } }

` After you get this relationship working, take a look at this talk if you need to refactor your relationship for gorm performance using an intermediary table. http://www.infoq.com/presentations/GORM-Performance

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top