我无法在 Jpa 单元测试中从 H2 获取数据



我已经设法在Jpa中验证了我的查询,这意味着它们正在运行,但它们没有返回任何内容,我不知道为什么。我的stockdata表中似乎有数据,因为如果我试图在表中插入两次相同的数据,我会得到"唯一索引或主键冲突",所以我似乎连接到了另一个H2数据库。

这是我的全部代码,从我试图开始工作的JUnit测试开始。

如果你没有看到这个问题,我仍然希望你有任何输入,因为我正在同时学习Spring和Spring引导,并且希望有任何指针!谢谢

// 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 javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Index;
import javax.persistence.Table;
@Entity
@Table(name = "stockdata",
indexes = {@Index(name="symbol_interval_type_index", columnList="symbol,intervalType", unique=false)}
)
public class StockData extends AuditModel {
private static final long serialVersionUID = 1L;
public static final int DAILY=1;
private StockKey key;
@Column
private float open;
@Column
private float high;
@Column
private float low;
@Column
private float close;
@Column(columnDefinition="adjusted_close")
private float adjustedClose;
@Column
private int volume;
@Column(columnDefinition="dividend_amount")
private float dividendAmount;
@Column(columnDefinition="split_coefficient")
private float splitCoefficient;
public StockData() {}
public StockData(StockKey key, float open, float high, float low, float close, float adjustedClose, int volume,
float dividendAmount, float splitCoefficient) {
super();
this.key = key;
this.open = open;
this.high = high;
this.low = low;
this.close = close;
this.adjustedClose = adjustedClose;
this.volume = volume;
this.dividendAmount = dividendAmount;
this.splitCoefficient = splitCoefficient;
}
@Id
public StockKey getKey() {
return key;
}
public void setKey(StockKey key) {
this.key = key;
}
public float getOpen() {
return open;
}
public void setOpen(float open) {
this.open = open;
}
public float getHigh() {
return high;
}
public void setHigh(float high) {
this.high = high;
}
public float getLow() {
return low;
}
public void setLow(float low) {
this.low = low;
}
public float getClose() {
return close;
}
public void setClose(float close) {
this.close = close;
}
public float getAdjustedClose() {
return adjustedClose;
}
public void setAdjustedClose(float adjustedClose) {
this.adjustedClose = adjustedClose;
}
public int getVolume() {
return volume;
}
public void setVolume(int volume) {
this.volume = volume;
}
public float getDividendAmount() {
return dividendAmount;
}
public void setDividendAmount(float dividendAmount) {
this.dividendAmount = dividendAmount;
}
public float getSplitCoefficient() {
return splitCoefficient;
}
public void setSplitCoefficient(float splitCoefficient) {
this.splitCoefficient = splitCoefficient;
}
@Override
public String toString() {
return "nStockData [key=" + key + ", open=" + open + ", high=" + high + ", low=" + low + ", close=" + close
+ ", adjustedClose=" + adjustedClose + ", volume=" + volume + ", dividendAmount=" + dividendAmount
+ ", splitCoefficient=" + splitCoefficient + "]";
}   
}

及其复合密钥:

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;
}
}

完整性的AuditModel:

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);
}

JUnit测试用来从查找All的股票服务类

package com.myorg.stockService.stockservice;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.myorg.stockService.entity.StockData;
import com.myorg.stockService.repository.StockRepository;

@Service
public class StockService {
@Autowired
private StockRepository stockRepository;
public List<StockData> getAllDailyStockData(String symbol) {
return stockRepository.getAllStockData(symbol, 1);
}
public List<StockData> findAll() {
return stockRepository.findAll();
}
}

应用程序类。请注意,断言在run方法中也会失败:

package com.myorg.stockService.stockservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
@SpringBootApplication
@EntityScan(basePackages = {"com.myorg.stockService"})
public class StockServiceApplication implements CommandLineRunner {
private Logger logger = LoggerFactory.getLogger(this.getClass());
public static void main(String[] args) {
SpringApplication.run(StockServiceApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
List<StockData> list = stockService.findAll();
assert(list.size() > 0);
}
}

我的src/main/resources文件夹下的3个文件:

application.properties:

spring.h2.console.enabled=true
spring.jpa.show-sql=true
logging.level.root=warn

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>

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

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

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

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

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

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

最新更新