开发者

Grails spring-security-core plugin expects a username column in the role table

I have a really strange problem. I've installed the spring-security-core 1.0.1 in my Grails 1.3.6 application and configured it according to the tutorial - tables are created orderly and populated by BootStrap.groovy. I'm using a PostgreSQL 8.4 database --the whole thing is running on my localhost. Now, the bootstrap works perfectly, but when I try to login I get an exception which says

org.hibernate.exception.SQLGrammarException: could not execute query

and further down:

Caused by: org.postgresql.util.PSQLException: ERROR: Column »username« does not exist

The query that fails is the following:

select
    authrole0_.id as id1_,
    authrole0_.version as version1_,
    authrole0_.authority as authority1_ 
from
    auth_role authrole0_ 
where
 开发者_C百科   username=?

and this is OK, because the auth_role table is not supposed to have username column. But why does Hibernate expect a username column, where it shouldn't be one?

Any clues as how to resolve this?

I've tried two different hibernate diaclects with no effect. I've noticed that the mapping of the table is somehow curious - with the lookup table mapped as well. Unfortunately it says in the documentation of the plugin that I'm not supposed to change it, because the class is needed by the plugin.

My classes look like that:

class AuthUser {

    String username
    String password
    boolean active
    boolean accountExpired
    boolean accountLocked
    boolean passwordExpired

    static mapping = {
        cache true
        username column: '`username`'
        password column: '`password`'
    }

    Set<AuthRole> getAuthorities() {
        UserRole.findAllByUser(this).collect { it.role } as Set
    }
}

import java.util.Set;

class AuthRole {

String authority

static constraints = {
    authority blank: false, unique: true
}
  }

  import org.apache.commons.lang.builder.HashCodeBuilder

class UserRole implements Serializable {

    AuthRole role
    AuthUser user

    boolean equals(other) {
        if (!(other instanceof UserRole)) {
            return false
        }

        other.user?.id == user?.id &&
                other.role?.id == role?.id
    }

    int hashCode() {
        def builder = new HashCodeBuilder()
        if (role) builder.append(role.id)
        if (user) builder.append(user.id)
        builder.toHashCode()
    }

    static UserRole get(long roleId, long userId) {
        find 'from UserRole where role.id=:roleId and user.id=:userId',
                [roleId: roleId, userId: userId]
    }

    static UserRole create(AuthRole role, AuthUser user, boolean flush = false) {
        new UserRole(role: role, user: user).save(flush: flush, insert: true)
    }

    static boolean remove(AuthRole role, AuthUser user, boolean flush = false) {
        UserRole instance = UserRole.findByRoleAndUser(role, user)
        instance ? instance.delete(flush: flush) : false
    }

    static void removeAll(AuthRole role) {
        executeUpdate 'DELETE FROM UserRole WHERE role=:role', [role: role]
    }

    static void removeAll(AuthUser user) {
        executeUpdate 'DELETE FROM UserRole WHERE user=:user', [user: user]
    }

    static mapping = {
        id composite: ['user', 'role']
        version false
    }
}

They are pretty much the way the plugin created them.

Thanks, al


OK, found it - "enabled" is a default value. In my class I defined "active" instead of "enabled".

Seems that the plugin is really touchy, when it comes to customizing ;-)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜