首页 > 解决方案 > Mybatis 自定义类型处理程序不起作用:java.lang.NoSuchMethodException: org.springframework.security.core.GrantedAuthority。()

问题描述

** 我正在对我的应用程序实施基于角色的访问控制。应用程序中有 3 个用户(管理员、教师、学生)具有相同的属性,所以我创建了一个 basedUser 实体让他们继承它。当我从数据库中选择它时,我希望获得用户的权限,所以我创建了一个类型处理程序,以在过程中将 String 类型的权限转换为 GrantedAuthority 类型,但我不知道为什么我一直收到此错误:**

嵌套异常是 org.mybatis.spring.MyBatisSystemException:嵌套异常是 org.apache.ibatis.reflection.ReflectionException:使用无效类型 () 或值 () 实例化接口 org.springframework.security.core.GrantedAuthority 时出错。原因:java.lang.NoSuchMethodException: org.springframework.security.core.GrantedAuthority.()] 根本原因

java.lang.NoSuchMethodException: org.springframework.security.core.GrantedAuthority.() at java.base/java.lang.Class.getConstructor0(Class.java:3349) ~[na:na] at java.base/java。 lang.Class.getDeclaredConstructor(Class.java:2553) ~[na:na] at org.apache.ibatis.reflection.factory.DefaultObjectFactory.instantiateClass(DefaultObjectFactory.java:60) ~[mybatis-3.5.4.jar:3.5 .4] 在 org.apache.ibatis.reflection.factory.DefaultObjectFactory.create(DefaultObjectFactory.java:53) ~[mybatis-3.5.4.jar:3.5.4] 在 org.apache.ibatis.reflection.factory.DefaultObjectFactory .create(DefaultObjectFactory.java:45) ~[mybatis-3.5.4.jar:3.5.4] at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.createResultObject(DefaultResultSetHandler.java:616) ~[mybatis-3.5. 4.jar:3.5.4] 在 org.apache.ibatis.executor.resultset.DefaultResultSetHandler。createResultObject(DefaultResultSetHandler.java:591) ~[mybatis-3.5.4.jar:3.5.4]

我一直在寻找这个问题的答案,但没有接近,有谁知道如何解决这个问题?

实体

@Data
public class BaseUser {

    protected Integer id;
    protected String username;
    protected String password;
    protected Date birthday;
    protected String email;
    protected String phone;
    protected String address;
    protected Boolean status;
    protected String creator;
    protected Date createTime;
    protected Date updateTime;
    protected Set<GrantedAuthority> authorities;

Mybatis xml查询:

  <select id="selectByAdminId" resultMap="AdminResultMap">
        SELECT a.id, a.password, a.admin_name, a.birthday, a.email, a.phone, a.address, a.status , au.authority as authority
        FROM admin a
        JOIN user_role ur ON ur.user_id = a.id
        JOIN role r ON r.id = ur.role_id
        JOIN role_authority ra ON ra.role_id = r.id
        JOIN authority au ON au.id = ra.authority_id
        WHERE a.id = #{id} and r.status = 1 AND au.status = 1
    </select>

Mybatis 映射

 <resultMap id="BaseUserResultMap" type="com.example.abstractionizer.student.management.system5.db.rmdb.entities.BaseUser">
        <id column="id" property="id" jdbcType="INTEGER"/>
        <result column="password" property="password" jdbcType="VARCHAR"/>
        <result column="admin_name" property="username" jdbcType="VARCHAR"/>
        <result column="birthday" property="birthday" jdbcType="DATE"/>
        <result column="email" property="email" jdbcType="VARCHAR"/>
        <result column="phone" property="phone" jdbcType="VARCHAR"/>
        <result column="address" property="address" jdbcType="VARCHAR"/>
        <result column="status" property="status" jdbcType="TINYINT"/>
        <collection property="authorities" ofType="org.springframework.security.core.GrantedAuthority">
            <result column="authority" jdbcType="VARCHAR" typeHandler="com.example.abstractionizer.student.management.system5.handlers.GrantedAuthorityTypeHandler"/>
        </collection>
    </resultMap>

    <resultMap id="AdminResultMap" type="com.example.abstractionizer.student.management.system5.db.rmdb.entities.Admin" extends="BaseUserResultMap">

    </resultMap>

类型处理程序


@Slf4j
@MappedJdbcTypes({JdbcType.VARCHAR})
public class GrantedAuthorityTypeHandler extends BaseTypeHandler<GrantedAuthority> {

    @Override
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, GrantedAuthority grantedAuthority, JdbcType jdbcType) throws SQLException {
        preparedStatement.setObject(i, grantedAuthority.toString(), jdbcType.TYPE_CODE);
    }

    @Override
    public GrantedAuthority getNullableResult(ResultSet resultSet, String s) throws SQLException {
        return new SimpleGrantedAuthority(resultSet.getString(s));
    }

    @Override
    public GrantedAuthority getNullableResult(ResultSet resultSet, int i) throws SQLException {
        return new SimpleGrantedAuthority(resultSet.getString(i));
    }

    @Override
    public GrantedAuthority getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
        return new SimpleGrantedAuthority(callableStatement.getNString(i));
    }
}

标签: javaspringormmybatis

解决方案


类型处理程序不适合您的使用。
您应该使用构造函数映射。

...
<collection property="authorities" 
  ofType="org.springframework.security.core.authority.SimpleGrantedAuthority">
  <constructor>
    <idArg column="authority" javaType="string" />
  </constructor>
</collection>
...

由于GrantedAuthority是一个接口,而 MyBatis 不知道如何实例化它,您需要SimpleGrantedAuthorityofType.


推荐阅读