使用@DataJpaTest 时,Hibernate @Formula 在 Spring 引导测试中不起作用

Hibernate @Formula not working in Spring boot Tests when using @DataJpaTest

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

@Formula("Customer_Id")
private int id

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

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

提前致谢。

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

如果你使用@DataJpaTest

By default, data JPA tests are transactional and roll back at the end of each test. See the relevant section in the Spring Framework Reference Documentation for more details

如果您使用 @SpringBootTest 则不是这样。 但是,如果您将 @Transational 添加到 Class,测试将失败。

解决方案:

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

Propagation.NOT_SUPPORTED states that if a physical transaction exists, then it will be suspended before continuing. This physical transaction will be automatically resumed at the end. After this transaction is resumed, it can be rolled back (in case of a failure) or committed.