我尝试使用@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,问题就会解决,但我不知道如何实现这一点。
1条答案
按热度按时间ocebsuys1#
这可以通过向测试类中添加下面的行来解决