bdbull
bdbull

Reputation: 188

grails (gorm) set contains and persists duplicates

I don't quite understand what is going on in my code right now. From what I understand, a groovy set does not contain duplicates. However, I am seeing duplicates in a set and also seeing duplicates persisted to the database. Although when retrieved from the database, the duplicates are not in the set.

I have two classes (some properties removed for brevity):

class EntityType {
    static hasMany = [attributes: Attribute]
}

class Attribute {
    String keyname
}

In my service, I pass in a jsonarray of attributes that are added to the EntityType using type.addToAttributes(attr). If I execute the same call more than once, duplicates are added to the Set. And when persisting, the duplicates are persisted. However, when I retrieve the Set from the database, the Set is retrieved without any duplicates. So the end result is it doesn't seem to hurt anything other than filling up the database table with unnecessary data.

What am I missing about Sets?

EDIT: Here's something odd I just noticed. The duplicates are not created for all of the attributes. Only n-1 duplicates are created. When iterating through the attribute jsonarry, the first attribute is not duplicated, but each one after that is. So if my array was {a:1,b:2,c:3} it would only create duplicates of b and c.

Upvotes: 3

Views: 693

Answers (2)

bdbull
bdbull

Reputation: 188

I figured this out. I ended up having to override the int hashCode() and boolean equals(Object o) methods as such:

@Override
int hashCode() {
    return keyname.hashCode() + id.hashCode()
}

@Override
boolean equals(Object o) {
    Attribute other = o as Attribute
    return keyname.equals(other.keyname) && id.equals(other.id)
}

While I don't really like this because it forces me to update these methods if I add new properties, it works for now.

Upvotes: 1

Dopele
Dopele

Reputation: 577

I would agree with aiolos that the most obvious reason is that you have multiple attributes with the same name.

you can prevent this making keyname unique

class Attribute {
    String keyname

    static constraints = {
        keyname unique:true
    }
}

Upvotes: 0

Related Questions