JpaRepository的findAll()方法返回空结果

6

JpaRepositoryfindAll() 方法返回空结果。我正在使用 Spring-boot、h2 数据库和 jpa 实现 rest 服务。

这是我的 schema.sql 文件:

CREATE TABLE IF NOT EXISTS `City` (
  `city_id` bigint(20) NOT NULL auto_increment,
  `city_name` varchar(200) NOT NULL,
PRIMARY KEY (`city_id`));

我的 data.sql 文件包含以下内容:

INSERT INTO City (city_id,city_name) VALUES(1,'EDE');
INSERT INTO City (city_id,city_name) VALUES(2,'DRUTEN');
INSERT INTO City (city_id,city_name) VALUES(3,'DELFT');

City实体:

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "City")
public class City {

  @Id
  @GeneratedValue
  @Column(name = "city_id")
  private Long cityId;

  @Column(name = "city_name")
  private String cityName;

  public Long getCityId() {
    return cityId;
  }

  public void setCityId(Long cityId) {
    this.cityId = cityId;
  }

  public String getCityName() {
    return cityName;
  }

  public void setCityName(String cityName) {
    this.cityName = cityName;
  }

}

JpaRepository 接口:

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface CityRepository extends JpaRepository<City, Long> {

    @Override
    List<City> findAll();
}

这里是我的控制器

@RestController
@RequestMapping("/city")
public class CityController {
    @Autowired
    private CityRepository cityRepository;

    @RequestMapping(method = RequestMethod.GET, value = "/all")
    public List<City> getAllCityList(){
        return cityRepository.findAll();
    }
}

我在这里做错了什么?参考文档: Spring文档


(意思是要查看Spring文档以解决问题)


5
移除你重写的findAll方法,因为JpaRepository中已经有一个了,不需要再次添加。同时禁用Hibernate的模式创建功能,因为这基本上会覆盖掉schema.sqldata.sql所做的工作。 - M. Deinum
@M.Deinum 我已经删除了 schema.sqldata.sql 文件,并且删除了重写的 findAll 方法,但是它仍然无法工作。 - fiskra
如果你删除那些文件,显然就什么都没有插入了... - M. Deinum
@M.Deinum 我在 application.properties 文件中添加了 spring.jpa.hibernate.ddl-auto=update,并将 schema.sqldata.sql 文件再次放入资源文件夹中。然后它就起作用了!非常感谢,这救了我的一天 :) - fiskra
4个回答

7
您有一个schema.sqldata.sql,这两个文件都在DataSource配置完成并准备就绪后执行。接下来会创建EntityManagerFactory,默认情况下(请参阅参考指南),它将为嵌入式类型(如H2)创建并删除数据库。

您可以通过将spring.jpa.hibernate.ddl-auto属性更改为除createcreate-drop之外的任何其他内容来覆盖此行为。

另一种解决方案是将data.sql重命名为import.sql,这将在Hibernate为您创建架构后执行。现在,您显然也可以删除schema.sql,因为Hibernate将创建架构。

如果这是为了学习目的,那么您应该没问题,但如果您想在实际生产系统中使用它,我建议您使用类似于Flyway这样的工具来管理您的模式。


3
据我理解,您希望在应用程序启动时执行SQL脚本,之后使用Hibernate?那么,您必须使用此处提到的选项之一,并设置spring.jpa.hibernate.ddl-auto=none。有关详细说明,请参见此处
祝好运!

0

这是一个对我有效的示例代码:

@DataJpaTest
@TestPropertySource(properties = {
        "spring.datasource.schema=classpath:/sql/schema.sql",
        "spring.datasource.data=classpath:/sql/data.sql",
        "spring.jpa.hibernate.ddl-auto=none"
})
class CalculatorRepositoryTest implements WithAssertions {

    @Autowired
    private CalculatorRepository repository;

    @Test
    void testAutoConfiguration() {
        assertThat(repository).isNotNull();
    }

    @Test
    void testInsertResult() {

        Result newResult = new Result();
        newResult.setOperation(OperationType.DIVISION.name());
        newResult.setValue(10);

        Result insertedResult = repository.save(newResult);

        assertAll(
                () -> assertThat(insertedResult).isNotNull(),
                () -> assertThat(insertedResult.getId()).isEqualTo(5L),
                () -> assertThat(insertedResult.getOperation()).isEqualTo(OperationType.DIVISION.name()),
                () -> assertThat(insertedResult.getValue()).isEqualTo(10)
        );
    }

    @Test
    void testSelectAllResults() {

        List<Result> results = repository.findAll();
        assertAll(
                () -> assertThat(results).isNotEmpty(),
                () -> assertThat(results.get(0).getOperation()).isEqualTo(OperationType.ADDITION.name()),
                () -> assertThat(results.get(0).getValue()).isEqualTo(5)
        );

    }

}

schema.sql

CREATE TABLE result(
    id INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
    operation VARCHAR(50) NOT NULL,
    value INT
);

data.sql

INSERT INTO result(id, operation, value) VALUES(1, 'ADDITION', 5);
INSERT INTO result(id, operation, value) VALUES(2, 'SUBTRACTION', 14);
INSERT INTO result(id, operation, value) VALUES(3, 'MULTIPLICATION', 10);
INSERT INTO result(id, operation, value) VALUES(4, 'DIVISION', 3);

首先,您不需要覆盖findAll()方法。它已经在您的接口中可用。

在配置您的schema.sqldata.sql文件时,第一件要做的事情是将此属性spring.jpa.hibernate.ddl-auto设置为none,以避免Hibernate为您创建模式。

spring.datasource.schema=classpath:/sql/schema.sql
spring.datasource.data=classpath:/sql/data.sql

这里我的 sql 文件位于此位置:test/resources/sql。否则,默认情况下,如果您将文件放在 test/resources 中,则不需要这些配置。

您可以在帖子中找到非常好的细节。


0
在我的情况下,我将已删除的列设置为null,并在JPA实体上使用了@Where(clause = "deleted='false'")。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接