repository.save() 如何工作,以及如何在 Spring 数据 JPA 中测试唯一约束
How does repository.save() work, and how to test unique constrains in Spring data JPA
我有一个 table“MyService”,在两列(命名空间和名称)上有唯一约束,Id 是 pk。
|姓名 |类型 |
| ------ | -------------- |
|编号 |长 |
|名称空间 |字符串 |
|姓名 |字符串 |
|价值 |字符串 |
我想编写单元测试以确保用户不能插入具有相同(命名空间和值)的新行。所以我这样编码:
@Test
public void insertDuplicateTest() {
Service service1 = Service.builder().namespace("ns").name("n1").value("v1").build();
repository.saveAndFlush(service1);
Service service2 = Service.builder().namespace("ns").name("n1").value("v2").build();
repository.saveAndFlush(service2);
}
我有两个问题:
- 根据我的理解,jparepository 将在实体不存在时插入,如果存在则合并。那么为什么这会引发错误:
org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [uk5pg2rvcx3fsu5dctsm3pyqkh6]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
- 如何完成此单元测试以检查是否存在错误或异常?
From my understanding jparepository will insert if the entity does not exist, and merge if is. So why this raise an error:
它会,但一个实体存在意味着一个实体具有相同的 主键 存在,其他 columns/attributes 对此并不重要(无论是否唯一) .
当 JPA 尝试插入异常时抛出异常(因为主要不存在)但由于违反了 UNIQUE
约束而失败。
如果您使用 @GeneratedValue
作为主键,它不会合并新创建的对象,而是为它们分配一个新的 ID 并插入它们(由于 UNIQUE
约束而失败)。
如果要合并对象,您需要使用不同的(非@GeneratedValue
)主键或修改现有对象(如service1
)。
How can I complete this unit test to check there is an error or exception?
如果您希望出现异常,只需使用 assertThrows
:
@Test
public void insertDuplicateTest() {
Service service1 = Service.builder().namespace("ns").name("n1").value("v1").build();
repository.saveAndFlush(service1);
Service service2 = Service.builder().namespace("ns").name("n1").value("v2").build();
assertThrows(DataIntegrityViolationException.class, () -> repository.saveAndFlush(service2);
}
我有一个 table“MyService”,在两列(命名空间和名称)上有唯一约束,Id 是 pk。 |姓名 |类型 | | ------ | -------------- | |编号 |长 | |名称空间 |字符串 | |姓名 |字符串 | |价值 |字符串 |
我想编写单元测试以确保用户不能插入具有相同(命名空间和值)的新行。所以我这样编码:
@Test
public void insertDuplicateTest() {
Service service1 = Service.builder().namespace("ns").name("n1").value("v1").build();
repository.saveAndFlush(service1);
Service service2 = Service.builder().namespace("ns").name("n1").value("v2").build();
repository.saveAndFlush(service2);
}
我有两个问题:
- 根据我的理解,jparepository 将在实体不存在时插入,如果存在则合并。那么为什么这会引发错误:
org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [uk5pg2rvcx3fsu5dctsm3pyqkh6]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
- 如何完成此单元测试以检查是否存在错误或异常?
From my understanding jparepository will insert if the entity does not exist, and merge if is. So why this raise an error:
它会,但一个实体存在意味着一个实体具有相同的 主键 存在,其他 columns/attributes 对此并不重要(无论是否唯一) .
当 JPA 尝试插入异常时抛出异常(因为主要不存在)但由于违反了 UNIQUE
约束而失败。
如果您使用 @GeneratedValue
作为主键,它不会合并新创建的对象,而是为它们分配一个新的 ID 并插入它们(由于 UNIQUE
约束而失败)。
如果要合并对象,您需要使用不同的(非@GeneratedValue
)主键或修改现有对象(如service1
)。
How can I complete this unit test to check there is an error or exception?
如果您希望出现异常,只需使用 assertThrows
:
@Test
public void insertDuplicateTest() {
Service service1 = Service.builder().namespace("ns").name("n1").value("v1").build();
repository.saveAndFlush(service1);
Service service2 = Service.builder().namespace("ns").name("n1").value("v2").build();
assertThrows(DataIntegrityViolationException.class, () -> repository.saveAndFlush(service2);
}