Spring 我能';在Jpa单元测试中,我无法从H2获取数据

Spring 我能';在Jpa单元测试中,我无法从H2获取数据,spring,spring-boot,spring-data-jpa,Spring,Spring Boot,Spring Data Jpa,我已经设法让我的查询在Jpa中得到验证——这意味着它们正在运行,但它们没有返回任何东西,我也不知道为什么。我的stockdata表中似乎有数据,因为如果我尝试在表中插入相同的数据两次,就会得到“唯一索引或主键冲突”,因此我似乎连接到了不同的H2数据库 下面是我的全部代码,从我正在尝试的JUnit测试开始 如果您没有看到问题,我仍然希望您能提供任何信息,因为我正在同时学习Spring和Spring boot,并且希望有任何指针!谢谢 // the unit test that fails - bu

我已经设法让我的查询在Jpa中得到验证——这意味着它们正在运行,但它们没有返回任何东西,我也不知道为什么。我的stockdata表中似乎有数据,因为如果我尝试在表中插入相同的数据两次,就会得到“唯一索引或主键冲突”,因此我似乎连接到了不同的H2数据库

下面是我的全部代码,从我正在尝试的JUnit测试开始

如果您没有看到问题,我仍然希望您能提供任何信息,因为我正在同时学习Spring和Spring boot,并且希望有任何指针!谢谢

// the unit test that fails - but should not (the list comes back empty)
package com.myorg.stockService.stockservice;

import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;

import com.myorg.stockService.entity.StockData;

@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes = {StockServiceConfig.class})
public class StockServiceApplicationTests {

    @Autowired
    StockService stockService;

    @Test
    public void contextLoads() {

        //List<StockData> list = stockService.getAllDailyStockData("TNDM");

        List<StockData> list = stockService.findAll();
        assert(list.size() > 0);
    }

}
及其复合键:

package com.myorg.stockService.entity;

import java.io.Serializable;
import java.sql.Timestamp;

import javax.persistence.Embeddable;

// This is the composite key class for StockData

@Embeddable
public class StockKey implements Serializable {

    private static final long serialVersionUID = 1L;

    private String symbol;
    private int intervalType;
    private Timestamp ts;

    public StockKey(String symbol, int intervalType, Timestamp timestamp) {

        this.symbol = symbol;
        this.intervalType = intervalType;
        this.ts= timestamp;
    }

    public String getSymbol() {
        return symbol;
    }
    public void setSymbol(String symbol) {
        this.symbol = symbol;
    }
    public int getIntervalType() {
        return intervalType;
    }
    public void setIntervalType(int intervalType) {
        this.intervalType = intervalType;
    }
    public Timestamp getTimestamp() {
        return ts;
    }
    public void setTimestamp(Timestamp timestamp) {
        this.ts = timestamp;
    }

}
完整性审核模型:

package com.myorg.stockService.entity;

import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;

@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
@JsonIgnoreProperties(
        value = {"createdAt", "updatedAt"},
        allowGetters = true
)
public abstract class AuditModel implements Serializable {

    private static final long serialVersionUID = 1L;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "created_at", nullable = false, updatable = false)
    @CreatedDate
    private Date createdAt;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "updated_at", nullable = false)
    @LastModifiedDate
    private Date updatedAt;

    public Date getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(Date createdAt) {
        this.createdAt = createdAt;
    }

    public Date getUpdatedAt() {
        return updatedAt;
    }

    public void setUpdatedAt(Date updatedAt) {
        this.updatedAt = updatedAt;
    }
}
我的回购类:

package com.myorg.stockService.repository;

import java.util.List;

import javax.transaction.Transactional;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import com.myorg.stockService.entity.*;

@Repository
@Transactional
public interface StockRepository extends JpaRepository<StockData, StockKey> {

    //@PersistenceContext
    //EntityManager entityManager;

    @Query("Select s from StockData s where s.key.symbol = ?1 AND s.key.intervalType= ?2")
    public List<StockData> getAllStockData(@Param("symbol") String symbol, @Param("intervalType") int intervalType);

}
data.sql-->注意-我还将此文件添加到src/test/resources下,但没有帮助

INSERT INTO stockdata(symbol,interval_type,ts,open,high,low,close,adjusted_close,volume,dividend_amount, split_coefficient) VALUES
    ('TNDM', 1, parsedatetime('2018-09-14', 'yyyy-MM-dd'), 112.1200, 113.7250, 112.1200, 112.9100, 112.4174, 26055620, 0.0000, 1.0000);
schema.sql:

// schema.sql:
CREATE TABLE stockdata (

    symbol VARCHAR NOT NULL,
    interval_type INT NOT NULL,
    ts TIMESTAMP NOT NULL,
    open DOUBLE NOT NULL,
    high DOUBLE NOT NULL,
    low DOUBLE NOT NULL,
    close DOUBLE NOT NULL,
    adjusted_close DOUBLE NOT NULL,
    volume INT NOT NULL,
    dividend_amount DOUBLE NOT NULL,
    split_coefficient DOUBLE NOT NULL,
    PRIMARY KEY(symbol, interval_type, ts)
);
pom.xml:

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.myorg.stockService</groupId>
    <artifactId>stock-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>stock-service</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

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

        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>

4.0.0
com.myorg.stockService
股票服务
0.0.1-快照
罐子
股票服务
SpringBoot的演示项目
org.springframework.boot
spring启动程序父级
2.1.0.1发布
UTF-8
UTF-8
1.8
org.springframework.boot
spring引导启动器数据jpa
org.springframework.boot
弹簧靴启动器jdbc
org.springframework.boot
SpringBootStarterWeb
com.h2数据库
氢
运行时
org.springframework.boot
弹簧起动试验
测试
org.springframework.boot
springbootmaven插件

当我尝试发布的代码时,它似乎有一些问题

  • 我在测试类中看不到用于ContextConfiguration的StockServiceConfig.class。所以我使用了StockServiceApplication.class。我还将其在包结构中提升了一个级别,以便进行组件扫描以找到存储库

  • 我不认为schema.sql正在运行。它只是让hibernate自动执行ddl。在application.properties中设置以下内容以停止此操作:

    spring.jpa.hibernate.ddl-auto=none
    
  • schema.sql中的CREATE表前面有一条注释。Sringboot似乎将所有这些连接在一起,并将整个事件视为一个注释行。在注释后添加分号:

    // schema.sql:;
    CREATE TABLE stockdata (
    
       symbol VARCHAR NOT NULL,
       ... etc
    
  • 您的StockKey有getTimestamp和setTimestamp,而字段是ts(与schema.sql匹配)。将它们更改为getTs和setTs,或者为列名提供合适的注释。还需要一个默认构造函数

  • StockData扩展了AuditModel,但schema.sql没有在AuditModel中定义任何列。要么定义列,要么不扩展AuditModel


  • 当我尝试时,发布的代码似乎有一些问题

  • 我在测试类中看不到用于ContextConfiguration的StockServiceConfig.class。所以我使用了StockServiceApplication.class。我还将其在包结构中提升了一个级别,以便进行组件扫描以找到存储库

  • 我不认为schema.sql正在运行。它只是让hibernate自动执行ddl。在application.properties中设置以下内容以停止此操作:

    spring.jpa.hibernate.ddl-auto=none
    
  • schema.sql中的CREATE表前面有一条注释。Sringboot似乎将所有这些连接在一起,并将整个事件视为一个注释行。在注释后添加分号:

    // schema.sql:;
    CREATE TABLE stockdata (
    
       symbol VARCHAR NOT NULL,
       ... etc
    
  • 您的StockKey有getTimestamp和setTimestamp,而字段是ts(与schema.sql匹配)。将它们更改为getTs和setTs,或者为列名提供合适的注释。还需要一个默认构造函数

  • StockData扩展了AuditModel,但schema.sql没有在AuditModel中定义任何列。要么定义列,要么不扩展AuditModel


  • 您需要添加到StockData类的构造函数中,stockKey=new stockKey(…,…,new Date());每次创建此实体时,您都需要生成一个密钥。启用SQL日志记录将是发现问题的良好开端。@Jonathan,StockData类中有一个使用StockKey的构造函数。@Alan,通过sell日志记录,您的意思是“spring.jpa.show SQL=true”吗?如果是,这已经在我的application.properties中。@Mike抱歉,我不能很好地解释您,在构造函数StockData类中,您需要实例stockKey=new stockKey();因为每次需要持久化时都必须生成此密钥。您需要添加到StockData类的构造函数中,stockKey=new stockKey(…,…,new Date());每次创建此实体时,您都需要生成一个密钥。启用SQL日志记录将是发现问题的良好开端。@Jonathan,StockData类中有一个使用StockKey的构造函数。@Alan,通过sell日志记录,您的意思是“spring.jpa.show SQL=true”吗?如果是,这已经在我的application.properties中。@Mike抱歉,我不能很好地解释您,在构造函数StockData类中,您需要实例stockKey=new stockKey();因为每次需要持久化时都必须生成此密钥。哇!你太棒了。我真是太感谢你了!!!我从你的帖子中学到了很多!说真的,我已经做了好几天了,你过来帮我解决这一切——你是最棒的!:)哇!你太棒了。我真是太感谢你了!!!我从你的帖子中学到了很多!说真的,我已经做了好几天了,你过来帮我解决这一切——你是最棒的!:)
    spring.jpa.hibernate.ddl-auto=none
    
    // schema.sql:;
    CREATE TABLE stockdata (
    
       symbol VARCHAR NOT NULL,
       ... etc