簡體   English   中英

@DataJpaTest 無法識別嵌入 id 中的非 null 限制

[英]@DataJpaTest does not recognize not null restrictions in embedded id

我正在嘗試使用@DataJpaTest注釋設置我的數據庫單元測試,以避免加載完整的 Spring 應用程序上下文。 但它的執行方式與我使用@SpringBootTest + 配置的 H2 數據庫時不同。 當我使用 H2 數據庫時,我在嘗試使用 null id 保存實體時收到適當的異常。

JdbcSQLIntegrityConstraintViolationException:列“ID_PART_2”不允許 NULL

但是當我使用@DataJpaTest自動配置的數據庫時,如此所述

默認情況下,它配置一個內存嵌入式數據庫,掃描@Entity 類,並配置 Spring 數據 JPA 存儲庫

該存儲庫允許插入具有 null 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自動配置的數據庫,但它沒有改變任何東西。

注意:問題僅發生在嵌入式 id 上。 對於我在堆棧跟蹤中看到的內容,如果javax.persistence.Id Spring JPA 在嘗試將此類實體保存到數據庫之前驗證失敗。

為什么使用@DataJpaTest@SpringBootTest時行為不同? 使用@DataJpaTest時使用什么數據庫? 如果 Spring 在這兩種情況下都使用 H2,我認為問題將得到解決,但我不知道如何實現這一點。

這可以通過添加來解決:

@org.springframework.transaction.annotation.Transactional(propagation = Propagation.NOT_SUPPORTED) 來測試 class。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM