@DataJpaTest не распознает ненулевые ограничения во встроенном идентификаторе - PullRequest
0 голосов
/ 17 апреля 2019

Я пытаюсь настроить свои модульные тесты БД, используя аннотацию @DataJpaTest, чтобы избежать полной загрузки контекста приложения Spring. Но он не работает так же, как когда я использую настроенную базу данных @SpringBootTest + H2. Когда я использую базу данных H2, я получаю надлежащее исключение при попытке сохранить сущность с нулевым идентификатором.

JdbcSQLIntegrityConstraintViolationException: NULL не допускается для столбца "ID_PART_2"

Но когда я использую БД, автоматически настроенную с использованием @DataJpaTest, как указано здесь

По умолчанию он настраивает встроенную базу данных в памяти, сканирует классы @Entity и настраивает репозитории Spring Data JPA

Хранилище позволяет вставлять сущности с нулевым идентификатором.

Код для моей сущности:

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), но это ничего не изменило.

ПРИМЕЧАНИЕ : проблема возникает только для встроенных идентификаторов. Что я вижу в стековых трассах, в случае javax.persistence.Id Spring JPA не проходит проверку, даже не пытаясь сохранить такую ​​сущность в базе данных.

Почему поведение отличается при использовании @DataJpaTest и @SpringBootTest? Какая база данных используется при использовании @DataJpaTest? Я думаю, что проблема была бы решена, если бы Spring использовал H2 в обоих случаях, но я не знаю, как этого добиться.

...