чаши Грааля (gorm) набор содержат и сохраняются дубликаты

Я не вполне понимаю то, что продолжается в моем коде прямо сейчас. Из того, что я понимаю, отличный набор не содержит дубликаты. Однако я вижу дубликаты в наборе и также вижу, что дубликаты сохранились к базе данных. Хотя, когда восстановлено от базы данных, дубликаты не находятся в наборе.

У меня есть два класса (некоторые свойства, удаленные для краткости):

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

class Attribute {
    String keyname
}

В моем обслуживании я прохожу в jsonarray признаков, которые добавляются к EntityType, используя type.addToAttributes (attr) . Если я выполняю то же самое требование несколько раз, дубликаты добавляются к Набору. И сохраняясь, дубликаты сохранены. Однако, когда я восстанавливаю Набор от базы данных, Набор восстанавливается без любых дубликатов. Таким образом, конечный результат, это, кажется, ничего не повреждает кроме заполнения таблицы базы данных с ненужными данными.

Что я пропускаю о Наборах?

Править: Вот что-то странное, которое я просто заметил. Дубликаты не создаются для всех признаков. Только дубликаты n-1 создаются. Повторяя через признак jsonarry, первый признак не дублирован, но каждый после этого. Таким образом, если бы мое множество было {a:1, b:2, c:3} оно только создало бы дубликаты b и c.

3
добавлено отредактировано
Просмотры: 2
nl ja de
Как вы создаете attr случай? Его взгляд как вы имеет многократный Признак случаи с тем же самым keyname ...
добавлено автор aiolos, источник
У меня есть обслуживание признака, которое возвращает или существующий Признак тем же самым именем или создает новое с именем. What' s странный то, что новые Признаки не создаются и сохранились, только новые отношения (EntityType-признак) создаются с существующим Признаком.
добавлено автор bdbull, источник

2 ответы

Я понял это. Я закончил тем, что имел необходимость отвергнуть , хэш-код интервала() и булев равняется (Возразите o) методы как таковые:

@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)
}

В то время как мне действительно не нравится это, потому что это вынуждает меня обновить эти методы, если я добавляю новые свойства, это работает на данный момент.

1
добавлено
У меня есть та же самая проблема с Чашами Грааля, используя и TreeSet и LinkedHashSet, но использование id в вашем равняется, и методы хэш-кода нарушает контракт - хэш-код и равняется, как, предполагается, основаны на неизменных ценностях для жизни Коллекции. Посмотрите onjava.com/pub/a/onjava/2006/09/13/…. Я все еще пытаюсь выяснить, как избежать двойных ссылок (буквально, хэш-код, равняется, compareTo, и даже ссылка памяти JVM обозначает, что они идентичны) в моих наборах, но мне don' t думают, что это - он.
добавлено автор Andy, источник
Кроме того, в зависимости от id сказал бы вам, что неспасенный признак с тем же самым keyname как спасенный признак не равен спасенному. Это может привести к дубликатам, на самом деле сохраняемым в базе данных.
добавлено автор Andy, источник

Я согласился бы с aiolos, что самая очевидная причина состоит в том, что у вас есть многократные признаки с тем же самым именем.

можно предотвратить это создание keyname уникальный

class Attribute {
    String keyname

    static constraints = {
        keyname unique:true
    }
}
0
добавлено
Это не многократные признаки с тем же самым именем, по крайней мере не в базе данных. Когда ряды отношений сохранены, они - действительно дублирующиеся строки. т.е. несколько рядов entitytype 1 и признака 3
добавлено автор bdbull, источник