grails one to many with additional column

128 views Asked by At

In my Grails project I need to have a 1:N relationship between two domain classes. So, I've created the following domain class:

class Receipt_HealthService {

   Receipt receipt
   HealthService healthService
   int quantity = 1

   static constraints = {
     }
}

and in Receipt I have the following:

 @NotNull
static hasMany = [healthServices:Receipt_HealthService]

So a new table is created that has got the id of both domain class and the quantity field.

When I call the save() method everything works well, but when I call the update() something does not work.

If user modifies the Receipt, removing one of the HealthService previously saved, and modifying the others, older HealthServices remain saved with the new ones. For example:

Receipt 1 created with :

  • HealthService 1 with quantity = 2
  • HealthService 2 with quantity = 3

Modification of Receipt 1:

  • HealthService 1 deleted
  • HealthService 2 modified with quantity = 2
  • HealthService 3 with quantity = 1

After the update() I have the following:

Receipt 1 with:

  • HealthService 1 with quantity = 2
  • HealthService 2 with quantity = 2
  • HealthService 3 with quantity = 1

I suppose that this behaviour is because of adding the new domain class. Do I maybe add manually the correct saving of HealthService in update()?

EDIT: the previous problem about save() is solved changing the code. I was using a method that is no more useful in my code. That method uses receiptInstance that, at the moment of method calling, is not filled with data and so I had the exception in save().

1

There are 1 answers

0
FrancescoDS On BEST ANSWER

I've solved this issue with the following code. I hope that someone gives me a comment about it.

receiptInstance.healthServices.collect().each {
        //I've tried to use receiptInstance.healthServices.clear()
        //but Set remains with all items 

        //delete item from Set
        receiptInstance.healthServices.remove(it) 
        //delete item from DB
        it.delete()
    }

         //save with flush to commit the delete
    if (!receiptInstance.save(flush: true)) {
        render(view: "edit", model: [receiptInstance: receiptInstance])
        return
    }