【问题标题】:r2dbc ReactiveCrudRepository keeps crashingr2dbc ReactiveCrudRepository 不断崩溃
【发布时间】:2023-03-26 15:26:01
【问题描述】:

我的 pom.xml 有以下依赖:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-r2dbc</artifactId>
  <version>2.3.3.RELEASE</version><!--$NO-MVN-MAN-VER$-->
</dependency>       

<dependency>
            <groupId>io.r2dbc</groupId>
            <artifactId>r2dbc-mssql</artifactId>
            <scope>runtime</scope>
</dependency>

我的属性如下:

spring.r2dbc.url=r2dbc:mssql://localhost:1433/Admin
spring.r2dbc.username=xxx
spring.r2dbc.password=xxx

回购看起来像:

@Repository
public interface UserRepository extends ReactiveCrudRepository<MyUser, String> {
    @Query("SELECT u.Username AS username, u.Password as password FROM Users u INNER JOIN Roles r ON u.RoleId=r.Roleid WHERE u.Username=@username") 
    public Mono<UserDetails> findByUsername(String username);
}

我的用户看起来像:

@SuppressWarnings("serial")
public class MyUser implements UserDetails {

    @Id
    private String username;
    private String password;

    public MyUser(String username, String password) {
        this.username = username;
        this.password = password;
    }
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return null;
    }

    @Override
    public String getPassword() {
        return password;
    }

    @Override
    public String getUsername() {
        return username;
    }

    @Override
    public boolean isAccountNonExpired() {
        return false;
    }

    @Override
    public boolean isAccountNonLocked() {
        return false;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return false;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }

我打开了 SQL 分析器并捕获了进来的查询,它是 100% 正确并返回正确的数据,但它似乎在反序列化时崩溃了。我设置了一个断点,它从不调用 MyUser 构造函数。如果我使用 Mono.just() 手动创建一个,该应用程序将按预期运行。

我收到以下异常:

java.lang.NullPointerException: null
    at org.springframework.data.r2dbc.core.DefaultDatabaseClient$DefaultTypedExecuteSpec.lambda$new$0(DefaultDatabaseClient.java:590) ~[spring-data-r2dbc-1.1.3.RELEASE.jar:1.1.3.RELEASE]
    Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
Error has been observed at the following site(s):
    |_ checkpoint ⇢ org.springframework.security.web.server.authentication.AuthenticationWebFilter [DefaultWebFilterChain]
    |_ checkpoint ⇢ org.springframework.security.web.server.authentication.AuthenticationWebFilter [DefaultWebFilterChain]
    |_ checkpoint ⇢ org.springframework.security.web.server.context.ReactorContextWebFilter [DefaultWebFilterChain]
    |_ checkpoint ⇢ org.springframework.security.web.server.header.HttpHeaderWriterWebFilter [DefaultWebFilterChain]
    |_ checkpoint ⇢ org.springframework.security.config.web.server.ServerHttpSecurity$ServerWebExchangeReactorContextWebFilter [DefaultWebFilterChain]
    |_ checkpoint ⇢ org.springframework.security.web.server.WebFilterChainProxy [DefaultWebFilterChain]
    |_ checkpoint ⇢ org.springframework.boot.actuate.metrics.web.reactive.server.MetricsWebFilter [DefaultWebFilterChain]
    |_ checkpoint ⇢ HTTP POST "/login?error" [ExceptionHandlingWebHandler]
Stack trace:
        at org.springframework.data.r2dbc.core.DefaultDatabaseClient$DefaultTypedExecuteSpec.lambda$new$0(DefaultDatabaseClient.java:590) ~[spring-data-r2dbc-1.1.3.RELEASE.jar:1.1.3.RELEASE]
        at java.base/java.util.function.BiFunction.lambda$andThen$0(BiFunction.java:70) ~[na:na]
        at io.r2dbc.mssql.MssqlResult.lambda$map$2(MssqlResult.java:169) ~[r2dbc-mssql-0.8.4.RELEASE.jar:0.8.4.RELEASE]

关于问题是什么的任何想法?这段代码例外:

    if (typeToRead.isInterface()) {
        this.mappingFunction = ColumnMapRowMapper.INSTANCE
                .andThen(map -> projectionFactory.createProjection(typeToRead, map));
    } else {
        this.mappingFunction = dataAccessStrategy.getRowMapper(typeToRead);
    }

【问题讨论】:

  • @username 可以为空吗?这就是你看到 NPE 的原因
  • @username 是正确的。我在 SQL 分析器中验证了查询。

标签: java spring spring-boot spring-data spring-data-r2dbc


【解决方案1】:
  1. 如果您使用的是存储库,则在您的代码中,MyUser 不会使用@Table 进行注释,例如here

  2. 如果您不使用 Spring Data R2dbc 中提供的 OR Mapping,您可以尝试使用 DatabaseClient 手动处理查询,如果您坚持编写自定义 SQL 脚本,它会更加灵活。例如。 here.

【讨论】:

  • 我尝试将 @Table(value="Users") 添加到 MyUser。我还尝试切换到您的示例中的 :username 和 R2dbcRepository。与上述相同的例外。
  • 我查看了示例中的 DatabaseClient。它在哪里初始化?我收到一条错误消息,指出 .sql 未定义。
  • 我认为你应该继续在 mssql 中使用@username。默认情况下,我认为 Spring Boot 会通过 URL 检测参数绑定策略。
  • DatabaseClient,R2dbcEntityTemplate也在你的Spring Boot应用中配置,你直接使用。
  • 对 ReactiveCrudRepository 的空异常有任何想法吗?希望在适合架构的情况下使用它。
【解决方案2】:

尝试将默认构造函数(没有参数的构造函数)添加到您的 MyUser 类。

【讨论】:

  • 我尝试添加一个默认构造函数,同样的异常。我运行了 SQL 分析器,查询是 100% 正确的,并且正在返回正确的数据。
  • 它没有命中任何一个构造函数。
猜你喜欢
  • 2021-05-03
  • 2020-06-21
  • 2012-09-03
  • 2015-08-08
  • 2018-05-24
  • 2013-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多