使用数据R2DBC FindbyId()与MSSQLSERVER兼容性使用H2时,Spring Boot 2.7.1失败(语法限制不良2)

发布于 2025-02-13 07:26:07 字数 2386 浏览 0 评论 0原文

我正在将Spring Boot 2.6.9应用程序升级到2.7.x行(2.7.1)。应用程序测试将H2与MS SQL Server兼容模式使用。

我已经创建了一个简单的示例项目来重现此问题: https://github.com/codepentent/boot -H2

分支:

  • 主:Spring Boot 2.7.1-测试KO
  • boot26:Spring Boot 2.6.9-测试可以

检查行为,只需运行 清洁测试

是代码的相关部分:

test应用

spring:
  r2dbc:
    url: r2dbc:h2:mem:///testdb?options=MODE=MSSQLServer;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE

程序。

CREATE SCHEMA IF NOT EXISTS [dbo];
CREATE TABLE IF NOT EXISTS [dbo].[CUSTOMER] (
    id INTEGER GENERATED BY DEFAULT AS IDENTITY,
    name VARCHAR(255) NOT NULL,
    CONSTRAINT PK__otp__D444C58FB26C6D28 PRIMARY KEY (id)
);

@Table("[dbo].[CUSTOMER]")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CustomerEntity {

    @Id
    @Column("id")
    private Integer id;

    @Column("name")
    private String name;

}

这些

public interface CustomerRepository extends ReactiveCrudRepository<CustomerEntity, Integer> {
}

./ mvnw ,如以下测试中可以看出的

@SpringBootTest
@RequiredArgsConstructor
@TestConstructor(autowireMode = ALL)
class BootH2ApplicationTests {

    private final CustomerRepository customerRepository;

    @Test
    void shouldSaveAndLoadUsers() {

        CustomerEntity joe = customerRepository.save(new CustomerEntity(null, "Joe")).block();

        customerRepository.findById(joe.getId()).block();

例外:

Caused by: io.r2dbc.spi.R2dbcBadGrammarException: 
Syntax error in SQL statement "SELECT [dbo].[CUSTOMER].* FROM [dbo].[CUSTOMER] WHERE [dbo].[CUSTOMER].id = $1 [*]LIMIT 2"; SQL statement:
SELECT [dbo].[CUSTOMER].* FROM [dbo].[CUSTOMER] WHERE [dbo].[CUSTOMER].id = $1 LIMIT 2 [42000-214]

r2dbCentityTemplate将SelectOne查询限制为2元素:

    public <T> Mono<T> selectOne(Query query, Class<T> entityClass) throws DataAccessException {
        return (Mono)this.doSelect(query.getLimit() != -1 ? query : query.limit(2), entityClass, this.getTableName(entityClass), entityClass, RowsFetchSpec::one);
    }

这将转化为限制n子句,而H2/SQL Server不支持。

不确定是否是某种H2/春季数据错误,还是有一种解决此问题的方法。

I'm upgrading a Spring Boot 2.6.9 application to the 2.7.x line (2.7.1). The application tests use H2 with MS SQL Server compatibility mode.

I've created a simple sample project to reproduce this issue: https://github.com/codependent/boot-h2

Branches:

  • main: Spring Boot 2.7.1 - Tests KO
  • boot26: Spring Boot 2.6.9 - Tests OK

To check the behaviour just run ./mvnw clean test

These are the relevant parts of the code:

Test application.yml

spring:
  r2dbc:
    url: r2dbc:h2:mem:///testdb?options=MODE=MSSQLServer;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE

schema.sql

CREATE SCHEMA IF NOT EXISTS [dbo];
CREATE TABLE IF NOT EXISTS [dbo].[CUSTOMER] (
    id INTEGER GENERATED BY DEFAULT AS IDENTITY,
    name VARCHAR(255) NOT NULL,
    CONSTRAINT PK__otp__D444C58FB26C6D28 PRIMARY KEY (id)
);

Entity

@Table("[dbo].[CUSTOMER]")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CustomerEntity {

    @Id
    @Column("id")
    private Integer id;

    @Column("name")
    private String name;

}

Data R2DBC Repository

public interface CustomerRepository extends ReactiveCrudRepository<CustomerEntity, Integer> {
}

The problem occurs when invoking customerRepository.findById(xxx), as can be seen in the following test

@SpringBootTest
@RequiredArgsConstructor
@TestConstructor(autowireMode = ALL)
class BootH2ApplicationTests {

    private final CustomerRepository customerRepository;

    @Test
    void shouldSaveAndLoadUsers() {

        CustomerEntity joe = customerRepository.save(new CustomerEntity(null, "Joe")).block();

        customerRepository.findById(joe.getId()).block();

Exception:

Caused by: io.r2dbc.spi.R2dbcBadGrammarException: 
Syntax error in SQL statement "SELECT [dbo].[CUSTOMER].* FROM [dbo].[CUSTOMER] WHERE [dbo].[CUSTOMER].id = $1 [*]LIMIT 2"; SQL statement:
SELECT [dbo].[CUSTOMER].* FROM [dbo].[CUSTOMER] WHERE [dbo].[CUSTOMER].id = $1 LIMIT 2 [42000-214]

The R2dbcEntityTemplate is limiting the selectOne query to 2 elements:

    public <T> Mono<T> selectOne(Query query, Class<T> entityClass) throws DataAccessException {
        return (Mono)this.doSelect(query.getLimit() != -1 ? query : query.limit(2), entityClass, this.getTableName(entityClass), entityClass, RowsFetchSpec::one);
    }

And this is translated into a LIMIT N clause which is not supported by H2/SQL Server.

Not sure if it's some kind of H2/Spring Data bug or there's a way to fix this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文