2014-02-03 3 views
1

В документе grails указано, что по умолчанию hasMany - это набор. Мой домен выглядит следующим образом:grails, hasMany, набор и дубликаты

class Employee { 
    String name; 
    String empId; 
    String password; 
    String contactNumber; 
    String emailId; 

    static hasMany = [roles : Role] 

    static belongsTo = [department : Department] 

    static constraints = { 
     contactNumber nullable : true 
     emailId nullable : true 
     empId unique : true 
     roles nullable : true 
     department nullable : true 
    } 

    static mapping = { 
     sort name : "asc" 
    } 
} 

//Role class 
class Role { 
    String role; 
    String roleId; 
} 

И следующий код в контроллере позволяет добавлять дублирующиеся записи в «ролей»:

roleListToBeAdded.each { r -> 
         println "Trying to add ${r}" 
         try { 
          employee.addToRoles(r).save(flush:true) 
         } catch (Exception e) { 
          println "failed to add ${r}: ${e}" 
         } 
        } 

почему это так?

Примечание: Если roleListToBeAdded имеет несколько записей той же роли (ибо пример: если запрос JSON выглядит следующим образом: { "rolesToBeAdded": [{ "роль": 33}, { "роль": 33} }), то он не добавляется два раза, но если сказать, что роль 33 уже добавлена, и я делаю новый запрос еще раз с ролью: 33, то он добавляет еще одну запись в таблицу employee_role.

+2

Что делает 'Role' класс выглядеть, в частности, его' 'equals' и hashCode' реализации? –

+0

Я отредактировал сообщение и включил класс Role. – vikas

ответ

1

Необходимо добавить соответствующие классы equals и hashCode в класс Роль, поскольку уникальность Set основана на равенстве Java, а не на идентификаторе базы данных. Определение равенства должно основываться на данных (например, имени роли), а не на идентификаторе базы данных, поскольку «временные» экземпляры (те, которые еще не были сохранены) имеют нулевые идентификаторы.

+0

Спасибо @ Ian Roberts, я попробую ваше решение. – vikas

+0

Вот код для того, что методы булевы равно (другие) { если (! (Другой InstanceOf Роль)) { возвращение ложным } other.role == Роль && other.roleId == Идентификатор роли } ИНТ хэш-код() { Защиты строитель = новый org.apache.commons.lang.builder.HashCodeBuilder.HashCodeBuilder() builder.append роли builder.append builder.toHashCode Идентификатор роль() } –

-1

Я думаю, что проблема заключается не только в реализации «Set» или «equals» или «hashcode», но и в классе Role. Этот класс

class Role { 
    String role; 
    String roleId; 
} 

В этом классе есть два ID: первый «Идентификатор роли», но это не является первичным ключом. В самом деле, если вы хотите, чтобы «Идентификатор роль» быть PK вы должны добавить статическую привязку к классу Role (следовать этому посту Stack Post, 10120708):

class Role { 
    String role; 
    String roleId; 
    static mapping = { 
     id column: 'roleId', type: 'varchar' 
    } 
} 

Если это отображение не установлено, есть неявное PK определяется как 'id' (второй :)). Если вы видите таблицу, рамки Grails создания чтения класса «Роль», вы увидите что-то вроде этого:

TableName Role 
id(This is PK)   role   roleId 
---      ---   --- 

Tht почему равна/хэш-код по умолчанию метод не похоже на работу, они делают сравнение между неявным идентификатором а не между ролями.

свиданья

Смежные вопросы