【问题标题】:Hibernate @Formula not working in Spring boot Tests when using @DataJpaTest使用 @DataJpaTest 时休眠 @Formula 在 Spring Boot 测试中不起作用
【发布时间】:2021-03-16 08:47:36
【问题描述】:

我正在尝试为 java spring 项目编写集成测试。 在代码中的某个时刻,我需要检查 customer.getId(),其中 ID 由 @Formula 注释创建,如下所示:(请记住 Customer_Id 是我的自动递增主键)

@Formula("Customer_Id")
private int id

我使用lombok 来生成getter 和setter 方法。我的测试数据库是 H2,我使用 Junit5 进行测试。我面临的问题是我无法测试getId() 的行为,因为当我用@DataJpaTest 注释测试时它总是0。我使它与 @SpringBootTest 一起工作,但我想坚持切片测试。

有没有办法让@DataJpaTest@Formulas 一起工作?

提前致谢。

@Entity(name="customers")
@Table(name="Customers")
@Getter
@Setter
@NoArgsConstructor
public class Customer{

    @Formula("Customer_Id")
    private int id;

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="Customer_Id", unique=true, nullable=false, precision=10)
    private int customerId;
}
// if it is annotated with @SpringBootTest the tests passes
@DataJpaTest
@ActiveProfiles("test")
@EnableJpaAuditing
class MyClassTests {

    @Autowired
    private CustomerRepository customerRepository;

    @Test
    void given_a_customer_should_have_customerId_and_id_equal(){
        Customer customer = new Customer();
        customerRepository.save(customer);
        // if i don't call findOneByCustomerId test fails for both @SpringBootTest and @DataJpaTest
        customer = customerRepository.findOneByCustomerId(customer.getCustomerId());
        assertEquals(customer.getCustomerId(), customer.getId()); // expected: 1, actual 0
    }
}

【问题讨论】:

  • 不清楚为什么需要以如此奇怪的方式复制customerId?你想达到什么目标?
  • 好点。我的客户表不遵循命名约定,但我仍然需要有公式,以便我可以查询一个名为 id 的字段,即使我的表没有它。
  • 您只需将customerId 重命名为id 即可,因为您通过@Column 注释明确指定了列名。
  • @SternK 在这个人为的示例中,可以避免公式 - 但是对于仍然需要测试的复杂公式并且 DataJpaTest 用作切片测试会发生什么?

标签: spring hibernate spring-data-jpa spring-data junit5


【解决方案1】:

如果你使用@DataJpaTest

默认情况下,数据 JPA 测试在最后是事务性和回滚 每个测试。请参阅 Spring Framework 中的 relevant section 参考文档了解更多详情

如果您使用@SpringBootTest,情况并非如此。 但是,如果您将 @Transational 添加到您的班级,测试将失败。

解决方案:

@DataJpaTest
@Transactional(propagation = Propagation.NOT_SUPPORTED)
class MyClassTests {
  ...

Propagation.NOT_SUPPORTED 指出,如果一个物理事务 存在,那么它将在继续之前被暂停。这种物理 交易将在结束时自动恢复。在这之后 事务恢复,它可以回滚(在失败的情况下) 或承诺。

【讨论】:

    猜你喜欢
    • 2014-07-31
    • 2017-01-05
    • 2020-08-13
    • 2020-02-03
    • 1970-01-01
    • 2019-03-28
    • 2018-01-01
    • 2020-11-07
    • 2012-09-01
    相关资源
    最近更新 更多