首页 > 解决方案 > Kotlin,SpringBoot(JPA)多个存储库的事务持久性问题

问题描述

我遇到了一个问题,我无法将多个实体保存到各自的存储库中。我究竟做错了什么???我能够坚持第一个实体,但不能坚持第二个。为什么会这样?

助手类:

@Component
class Helper @Autowired constructor(
        private val requestRepository: RequestRepository,
        private val exchangeRateRepository: ExchangeRateRepository,
        private val exchangeRateResultRepository: ExchangeRateResultRepository,
        private val responseRepository: ResponseRepository
) {

    fun processClientExchangeRateResponses(base: String, listSymbols: List<String>, clientResponses: List<ClientExchangeRateResponse>) {
        requestRepository.save(Request("Test", "Test"))
        responseRepository.save(Response(10.0, "Test", 12, 12, "Hello"))

    }
}

请求实体:

@Entity
@Table(name = "requests")
class Request(
        @Column(name = "base", updatable = false, nullable = false)
        private val base: String,

        @Column(name = "requestObject", updatable = false, nullable = false)
        private val requestObject: String
) {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "native")
    @GenericGenerator(name = "native", strategy = "native")
    @Column(name = "id", updatable = false, nullable = false)
    val id: Long = 0

    @CreationTimestamp
    @Column(name = "created_at", nullable = false, columnDefinition = "DATETIME")
    private val createdAt: ZonedDateTime? = getCurrentDateTime()

    @CreationTimestamp
    @Column(name = "updated_at", nullable = false, columnDefinition = "DATETIME")
    private val updatedAt: ZonedDateTime? = getCurrentDateTime()

    private fun getCurrentDateTime(): ZonedDateTime? {
        return ZonedDateTime.now()
    }
}

响应实体:

@Entity
@Table(name = "responses")
class Response(
        private val responseTime: Double,
        private val currencyType: String,
        private val exchangeId: Long,
        private val requestId: Long,
        private val responseObject: String
) {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "native")
    @GenericGenerator(name = "native", strategy = "native")
    @Column(name = "id", updatable = false, nullable = false)
    val id: Long = 0

    @CreationTimestamp
    @Column(name = "created_at", nullable = false, columnDefinition = "DATETIME")
    private val createdAt: ZonedDateTime? = getCurrentDateTime()

    @CreationTimestamp
    @Column(name = "updated_at", nullable = false, columnDefinition = "DATETIME")
    private val updatedAt: ZonedDateTime? = getCurrentDateTime()
}

请求存储库

@Repository
interface RequestRepository : JpaRepository<Request, Long>

响应库

@Repository
interface ResponseRepository : JpaRepository<Response, Long>

主类:

@EnableScheduling
@SpringBootApplication
class RatesApplication

    fun main(args: Array<String>) {
        runApplication<RatesApplication>(*args)
    }

POM 文件:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>globee</groupId>
    <artifactId>rates</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>rates</name>
    <description>Rates</description>

    <repositories>
        <repository>
            <id>jcenter</id>
            <url>https://jcenter.bintray.com/</url>
        </repository>
    </repositories>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>11</java.version>
        <maven.test.plugin.version>2.22.2</maven.test.plugin.version>
        <kotlin.version>1.3.72</kotlin.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-jpa -->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>2.3.4.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>2.2.2.RELEASE</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.6</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.module</groupId>
            <artifactId>jackson-module-kotlin</artifactId>
        </dependency>

        <!--
         Encountered some problems with this maven dependency. See the following two links for this solution
         https://github.com/ascclemens/khttp and
         https://khttp.readthedocs.io/en/latest/user/install.html#jitpack &ndash;&gt;
     -->
        <dependency>
            <groupId>khttp</groupId>
            <artifactId>khttp</artifactId>
            <version>1.0.0</version>
        </dependency>

        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-reflect</artifactId>
        </dependency>

        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-stdlib-jdk8</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.liquibase/liquibase-core -->
        <dependency>
            <groupId>org.liquibase</groupId>
            <artifactId>liquibase-core</artifactId>
            <version>1.9.5</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.13.3</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.version}</version>
        </dependency>

    </dependencies>

    <build>
        <sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
        <testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                        <configuration>
                            <mainClass>globee.RatesApplication</mainClass>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <!-- https://mvnrepository.com/artifact/org.liquibase/liquibase-maven-plugin -->
            <plugin>
                <groupId>org.liquibase</groupId>
                <artifactId>liquibase-maven-plugin</artifactId>
                <version>3.10.2</version>
                <configuration>
                    <propertyFileWillOverride>true</propertyFileWillOverride>
                    <propertyFile>src/main/resources/liquibase.properties</propertyFile>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.jetbrains.kotlin</groupId>
                <artifactId>kotlin-maven-plugin</artifactId>
                <configuration>
                    <args>
                        <arg>-Xjsr305=strict</arg>
                    </args>
                    <compilerPlugins>
                        <plugin>spring</plugin>
                    </compilerPlugins>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>org.jetbrains.kotlin</groupId>
                        <artifactId>kotlin-maven-allopen</artifactId>
                        <version>${kotlin.version}</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>
</project>

标签: spring-bootkotlinjpaliquibase

解决方案


底层的 Hibernate 层可能会影响您在此处的保存。通常实体不会被写入数据库,除非您调用commitflush。还有另一种方法可以立即将实体写入 DB。它被称为saveAndFlush。如果您想立即坚持下去,也许您应该考虑使用这种方法。

也许这篇文章可能会澄清差异:https ://www.baeldung.com/spring-data-jpa-save-saveandflush


推荐阅读