5

I have a pretty simple hasMany relationship where a "product" hasMany "packages". I'm running a script to try and fill in the data, which works fine on the first run. However on the second run, it starts inputing duplicates, which I though was not possible for a hasMany

package = Package.findBySourceId(packageId) ?: new Package(name:packageName, price:packagePrice, sourceId:packageId).save(flush:true)

product = Product.findBySourceId(productId)                 
product.addToPackages(package)
product.save(flush:true)

When I put on sql logging on, I can see that sometimes the select that should run on the addToPackages call is not run. It just does the select to find the product and then a straight insert into the join table.

I don't want to add the exact queries because of work but basically its like

Select -> for the initial package which it finds

Select -> for product which it finds by the product id

Insert -> insert into the join table without even a select to check if an entry exists

However sometimes instead of that insert it will run a select and find the match and the process will start over. No idea on the logic going on behind grails here. Keep in mind, I have a script running that's pulling the data with thousands of line, is this a session issue somehow?

Rob
  • 51
  • 3
  • What does your Package class look like? Do you have the correct constraints set on the sourceId property? – Pat May 18 '11 at 15:17
  • Sounds like you have some sort of non-deterministic behaviour going on. uck... – netbrain May 19 '11 at 10:09

2 Answers2

3

Have you used a List or Set for your collection on the "many" side of your one-to-many? The default is a Set, which should constrain against duplicates. If you've mapped the collection using a List, then you may have created the problem.

Alternatively, verify that the identity property "package" has the correct behaviors for equals() and hashCode().

Greg
  • 116
  • 3
  • how would you map the collection to use a list instead of a set? – Martin Klosi Nov 01 '11 at 09:29
  • @MartinKlosi Just declare `List myObjects` before `static hasMany = [myObjects: MyObject]`. See http://stackoverflow.com/questions/520187/defining-default-sort-order-in-grails-gorm for an example. – Antoine Nov 17 '11 at 07:53
0

See Domain hasMany association using a List is adding duplicate items when the parent is saved

cweston
  • 11,297
  • 19
  • 82
  • 107
Jay Prall
  • 5,295
  • 5
  • 49
  • 79