@DataJpaTest无法识别嵌入式ID中的非null限制

时间:2019-04-17 13:53:33

标签: java unit-testing spring-boot spring-data-jpa spring-boot-test

我正在尝试使用@DataJpaTest注释设置数据库单元测试,以避免加载完整的Spring应用程序上下文。但是它的执行方式与使用@SpringBootTest +配置的H2数据库时不同。当我使用H2数据库时,尝试保存具有空ID的实体时会收到适当的异常。

  

JdbcSQLIntegrityConstraintViolationException:“ ID_PART_2”列不允许使用NULL

但是当我使用here所述的@DataJpaTest自动配置的数据库时

  

默认情况下,它配置内存中的嵌入式数据库,扫描@Entity类,并配置Spring Data JPA存储库

存储库允许插入具有空ID的实体。

我实体的代码是:

package com.mycompany.test.db;

import lombok.Data;

import javax.persistence.*;
import java.io.Serializable;

@Data
@Entity
@Table(name = "MY_TABLE", schema = "MY_SCHEMA")
public class MyEntity {

    //Works fine when using @Id
//    @Id
//    @Column(name = "ID", nullable = false)
//    private String id;

    @EmbeddedId
    private MyId myId;

    @Data
    @Embeddable
    public static class MyId implements Serializable {

        //Single field reproduces the problem
//        @Column(name = "ID_PART_1", nullable = false)
//        private String idPart1;
        @Column(name = "ID_PART_2", nullable = false)
        private String idPart2;
    }
}

我正在使用基本的CRUD存储库CrudRepository<MyEntity, MyEntity.MyId>

我的测试代码如下:

package com.mycompany.test.db;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest//works as expected
//@DataJpaTest//doesn't work
public class MyRepositoryTest {

    @Autowired
    private MyRepository repository;

    private MyEntity.MyId createMyId(String part1, String part2){
        MyEntity.MyId myId = new MyEntity.MyId();
//        myId.setIdPart1(part1);
        myId.setIdPart2(part2);
        return myId;
    }

    @Test
    public void testSaveAndRead(){
        MyEntity entity = new MyEntity();
        entity.setMyId(createMyId("part1", "part2"));

        repository.save(entity);
        Assert.assertNotNull(repository.findById(createMyId("part1", "part2")));
    }

    @Test
    public void testSaveWithNoPrimaryKeyFails(){
        try{
            MyEntity entity = new MyEntity();
            entity.setMyId(createMyId("part1", null));
            repository.save(entity);
            Assert.fail();
        }catch(Exception expected){
            expected.printStackTrace();
        }
    }
}

我还尝试通过添加@DataJpaTest来禁用使用@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)自动配置的数据库,但是它没有任何改变。

注意:仅嵌入式ID会出现问题。对于我在stacktraces中看到的内容,在javax.persistence.Id的情况下,Spring JPA甚至在尝试将此类实体保存到数据库之前都无法通过验证。

为什么使用@DataJpaTest@SpringBootTest时行为会有所不同?使用@DataJpaTest时使用什么数据库?我认为,如果Spring在这两种情况下都使用H2,就可以解决问题,但我不知道该如何实现。

0 个答案:

没有答案