Strange Grails行为在bootstrap中填充List

Sni*_*ite 0 grails grails-orm

我对一个奇怪的Grails行为感到疯狂.

我得到一个域类用户:

class User {

    String firstName
    String token
    List roles = [] as List

    static constraints = {
    }
}
Run Code Online (Sandbox Code Playgroud)

我像这样修改我的BootStrap.groovy来填充5个用户实例:

class BootStrap {

    def init = { servletContext ->
        switch (Environment.getCurrent()) {
            case 'DEVELOPMENT':
                def user1 = new User(
                    id: 1,
                    firstName: 'Enricot',
                    token: 'L\'abricot'
                )
                user1.roles.add('ROLE_USER')
                user1.save(failOnError: true)
                def user2 = new User(
                    id: 2,
                    firstName: 'Arnaud',
                    token: 'Dauphin')
                user2.roles.add('ROLE_USER')
                user2.roles.add('PERM_WRITE')
                user2.save(failOnError: true)
                def user3 = new User(
                    id: 3,
                    firstName: 'Magalie',
                    token: 'La banane')
                user3.roles.add('ROLE_USER')
                user3.roles.add('PERM_READ')
                user3.save(failOnError: true)
                def user4 = new User(
                    id: 4,
                    firstName: 'Jeremy',
                    token: 'Wistiti')
                user4.roles.add('ROLE_USER')
                user4.roles.add('ROLE_ADMIN')
                user4.save(failOnError: true)
                def user5 = new User(
                    id: 5,
                    firstName: 'Jimini',
                    token: 'Criquet')
                user5.roles.add('ROLE_USER')
                user5.roles.add('ROLE_INTERACTIONS')
                user5.save(failOnError: true)
                break
            case "test":
                DataBuilder.init()
                break
        }
    }
    def destroy = {
    }
}
Run Code Online (Sandbox Code Playgroud)

在我的控制器中,当我获得一个用户时,所有字段都是corect,除了List.

如果我做 :

def user = User.get(1)
println user.firstName // Output is "Enricot"
println user.token // Output is "L'abricot"
println user.roles // Output is "[]" and not "[ROLE_USER]"
Run Code Online (Sandbox Code Playgroud)

尝试像这样的填充对象并没有解决我的问题:

def user1 = new User(
        id: 1,
        firstName: 'Enricot',
        token: 'L\'abricot',
        roles: ['ROLE_USER']).save(failOnError: true)
Run Code Online (Sandbox Code Playgroud)

我试过双引号,简单的引用.

最有趣的部分是当我在制作"user.roles"INTO BootStrap.groovy时,我得到了正确的List.

这对我没有意义,欢迎任何帮助,

Bur*_*ith 6

这不奇怪的行为,你做错了:)

添加要保持持久性的字段时,需要向Grails提供有关如何存储它的信息.只是一个简单的List信息是不够的.如果它是其他域类的列表,它将创建一个外键并存储id.如果它是一个字符串列表,它会将它们存储为varchars.如文档中所示,您需要执行以下操作:

class User {
   String firstName
   String token
   static hasMany = [roles: String]
}
Run Code Online (Sandbox Code Playgroud)

这会将后备集合更改为a Set,但这对于角色来说可能是正确的,因为您不关心排序并希望获得唯一性.如果您确实需要订购,请添加一个未初始化的List字段以向Grails发送您不想要的信号Set:

class User {
   String firstName
   String token
   List roles
   static hasMany = [roles: String]
}
Run Code Online (Sandbox Code Playgroud)

这会更改您填充数据的方式.而不是直接添加到集合,使用addToRoles为您添加的动态方法:

class BootStrap {
   def init = { ctx ->
      environments {
         development {
            def user1 = new User(firstName: 'Enricot', token: 'L\'abricot')
            user1.addToRoles('ROLE_USER')
            user1.save(failOnError: true)
            def user2 = new User(firstName: 'Arnaud', token: 'Dauphin')
            user2.addToRoles('ROLE_USER')
            user2.addToRoles('PERM_WRITE')
            user2.save(failOnError: true)
            def user3 = new User(firstName: 'Magalie', token: 'La banane')
            user3.addToRoles('ROLE_USER')
            user3.addToRoles('PERM_READ')
            user3.save(failOnError: true)
            def user4 = new User(firstName: 'Jeremy', token: 'Wistiti')
            user4.addToRoles('ROLE_USER')
            user4.addToRoles('ROLE_ADMIN')
            user4.save(failOnError: true)
            def user5 = new User(firstName: 'Jimini', token: 'Criquet')
            user5.addToRoles('ROLE_USER')
            user5.addToRoles('ROLE_INTERACTIONS')
            user5.save(failOnError: true)
         }
         test {
            DataBuilder.init()
         }
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

有关BootStrap.groovy中环境块支持的信息,请参阅http://grails.org/doc/latest/guide/conf.html#environments.

另请注意,由于您未使用已分配的ID,因此我删除了显式ID值,因此会忽略这些值.

最后,看起来你正在推动自己的安全.不要这样做.使用经过验证的框架.这两个Spring Security的核心四郎是功能强大且易于上手.