Javers - mysql 外键约束失败

问题描述 投票:0回答:2

我是javers新手。为我的应用程序启动了 POC,但在提交时收到 SQL_EXCEPTION,因为 mysql 的“last_insert_id()”函数返回“0”。

我做了什么:

  • 添加在 spring boot maven 中启动(javers core & javers mysql)
  • 创建了与我的数据库架构的连接
  • 获取了 5 月数据库中的所有表(jv_global_id、jv_commit 等..)

问题:

我正在使用 spring boot 2.0 和 mysql 版本 5.7 我调试了 问题深入,发现当 Javers 代码 'org.javers.repository.sql.session.Session.java'方法 'executeInsertAndGetSequence' 第 40 行,尝试查找主键 返回零“0”。 根据代码,mysql方言不支持 序列,以便使用 mysql 函数从 keyGenerator 生成一个值 'last_insert_id()' 最终返回零。

我收到以下错误:

SQL_EXCEPTION: Cannot add or update a child row: a foreign key constraint fails (`jv_snapshot`, CONSTRAINT `jv_snapshot_commit_fk` FOREIGN KEY (`commit_fk`) REFERENCES `jv_commit` (`commit_pk`))\nwhile executing sql: INSERT INTO thinkhr_portal.jv_snapshot ( type, global_id_fk, commit_fk, version, state, changed_properties, managed_type ) VALUES  ( ?,?,?,?,?,?,? )

我想知道,如果javers不支持mysql版本5.7,或者我的javers配置中还有其他需要注意的地方。

foreign-keys sqlexception audit-trail javers
2个回答
1
投票

我遇到了同样的问题,这是由于每次在 ConnectionProvider 中创建一个新连接。 Javers 试图通过运行

select last_insert_id()
来获取提交 id,并且在新连接中,它始终返回 0。

您希望您的连接提供商是这样的:

        ConnectionProvider connectionProvider = new ConnectionProvider() {
            private Connection conn;
            @Override
            public Connection getConnection() throws SQLException {
                if (conn == null) {
                    conn = buildNewConnection();
                }
                return conn;
            }
        };

0
投票

叶戈尔的回答有帮助。

需要创建自定义连接提供程序以重用现有连接。

public class JaversConnectionProvider implements ConnectionProvider  {
    private final DataSource dataSource;
    private Connection conn;

    public JaversConnectionProvider(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    @Override
    public Connection getConnection() throws SQLException {
        if (conn == null || conn.isClosed()) {
            conn = buildNewConnection();
        }
        return conn;
    }

    private Connection buildNewConnection() throws SQLException {
        // Obtain a new connection from the DataSource
        return dataSource.getConnection();
    }
}

并在 Javers 配置中使用它

@Configuration
public class JaversConfiguration {

    @Bean
    public Javers javers(DataSource dataSource) {

        JaversConnectionProvider connectionProvider = new JaversConnectionProvider(dataSource);
        JaversSqlRepository sqlRepository = SqlRepositoryBuilder
                                                .sqlRepository()
                                                .withConnectionProvider(connectionProvider)
                                                .withDialect(DialectName.MYSQL)
                                                .build();

        return JaversBuilder
            .javers()
            .registerJaversRepository(sqlRepository)
            .build();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.