如何在启动时验证 Spring Data JPA 查询?
Posted
技术标签:
【中文标题】如何在启动时验证 Spring Data JPA 查询?【英文标题】:How to validate Spring Data JPA Queries on Startup? 【发布时间】:2014-01-14 01:21:12 【问题描述】:给定一个像这样的 Spring Data JPA 存储库。
public interface ProductRepository extends CrudRepository<Product, Long>, QueryDslPredicateExecutor<Product>
@Query("select p from Product p where p.attributes[?1] = ?2")
List<Product> findByAttributeAndValue(String attribute, String value);
如何让 Spring Data JPA 在启动时验证每个查询。例如,当我在 hibernate 中使用命名查询并且查询在语法上不正确或属性名称错误时,hibernate 会抱怨。
是否可以配置 spring 数据以在启动时验证查询?
【问题讨论】:
您不想在没有控制逻辑的情况下运行查询。假设您有一个delete from Product
方法。进行测试。
@MarkusMalkusch 我只想验证查询而不运行它们,如果查询引用不存在的属性或实体,或者有无法解析的语法错误,请在 satrtup 了解.
@ams 没有要求在启动时运行查询,而是验证它们。如果查询包含未映射到您的代码的无效 JPQL 或实体/属性名称,那么您希望获得快速失败行为,因此在服务器启动时,异常会告诉您您的查询无效。顺便说一句:hibernate 不会按照您的假设来验证命名查询。见这里:***.com/questions/27565706/…
【参考方案1】:
与其在启动时验证它,我建议您为此创建一个可以由您的持续集成服务器执行的测试。由于您已经在使用 Spring,因此创建一个 Embedded Database 非常简单,您可以使用已知的测试数据对其进行初始化。
创建两个文件schema.sql
是实际的生产数据架构,test-data.sql
包含一些已知的测试数据。接下来,创建一个单独的测试应用程序上下文:
<beans ...>
<jpa:repositories base-package="com.example.repositories" />
<jdbc:embedded-database id="dataSource">
<jdbc:script location="classpath:schema.sql"/>
<jdbc:script location="classpath:test-data.sql"/>
</jdbc:embedded-database>
<tx:annotation-driven/>
<!-- more beans -->
</beans>
或基于 Java 的配置:
@Configuration
@EnableJpaRepositories("com.example.repositories")
@EnableTransactionManagement
public class TestConfig
@Bean(destroyMethod = "shutdown")
public void EmbeddedDatabase embeddedDatabase()
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
return builder.setType(H2).addScript("schema.sql").addScript("test-data.sql").build();
// more beans
接下来,为ProductRepository
创建一个测试:
@ContextConfiguration([reference to your xml or Java application context])
@RunWith(SpringJUnit4ClassRunner.class)
@Transactional
public class ProductRepositoryTest
@Autowired
ProductRepository repository;
@Test
public void findProductByAttributeAndValue()
List<Product> actual = repository.findByAttributeAndValue("attr", "val");
// add assertions that 'actual' contains the expected data from the test-data.sql
在测试类中添加@Transactional
将导致数据库在每个测试方法完成后自动回滚。因此,所有测试都将具有相同的数据库状态(由 test-data.sql
指定),即使在测试中执行存储库写入操作也是如此。
【讨论】:
我已经有一个相当不错的测试套件,但它需要一段时间才能运行 :) 更喜欢在启动时只对查询进行语法检查的方法。【参考方案2】:您可以在 bean 上创建一个带有 @PostCreate
注释的方法并调用存储库方法,这样任何异常都会立即发生。多的话就麻烦了。
可能更合适的方法是对这些存储库方法进行单元测试。
【讨论】:
而且,仅仅调用方法是不够的,因为如果结果为空,可能仍然存在潜在的转换异常。以上是关于如何在启动时验证 Spring Data JPA 查询?的主要内容,如果未能解决你的问题,请参考以下文章
如何通过 Spring Data JPA 了解底层数据库名称
处理 JPA 规范和 spring-data-jpa 时如何使用声明 Stream 作为返回类型
从控制台应用程序使用带有休眠功能的spring-data-jpa时如何延迟加载收集
在 Spring Data JPA 中,如何在运行时添加实体?
如何在实现 Spring Data JPA AuditorAware 接口时获取 getUserPrincipal().getUserName()