spring-data-jpa @DataJpaTest无法识别嵌入ID中的非空限制

5w9g7ksd  于 2022-11-10  发布在  Spring
关注(0)|答案(1)|浏览(175)

我尝试使用@DataJpaTest注解来设置db单元测试,以避免加载完整的Spring应用程序上下文。但它的执行方式与我使用@SpringBootTest+配置的H2数据库时不同。当我使用H2数据库时,我在尝试使用空id保存实体时收到适当的异常。
JdbcSQL完整性约束违反异常:列“ID_PART_2”不允许为NULL
但是,当我使用自动配置的数据库时,使用@DataJpaTest,如此处所述
缺省情况下,它配置内存中的嵌入式数据库,扫描@Entity类,并配置SpringDataJPA存储库
系统信息库允许插入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();
        }
    }
}

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

注意:问题只发生在内嵌的id。对于我在stacktraces中看到的情况,如果是javax.persistence.Id Spring JPA,则在尝试将此类实体保存到数据库之前验证失败。

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

ocebsuys

ocebsuys1#

这可以通过向测试类中添加下面的行来解决

@org.springframework.transaction.annotation.Transactional(propagation = Propagation.NOT_SUPPORTED)

相关问题