当前位置: 首页 > 知识库问答 >
问题:

repository.save()如何工作,以及如何测试Spring数据JPA中的唯一约束

农飞星
2023-03-14

我有一个表“MyService”,对两列(名称空间和名称)有唯一的约束,Id是主键名称|类型| |-------------------id |长| |命名空间|字符串| |名称|字符串| |值|字符串|

我想编写单元测试以确保用户不能插入具有相同(命名空间和值)的新行。所以我这样编码:

@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);
}

我有两个问题:

  1. 据我所知,如果实体不存在,jparepository将插入,如果实体存在,jparepository将合并。那么,为什么会出现错误:

组织。springframework。道。DataIntegrityViolationException:无法执行语句;SQL[无];约束[uk5pg2rvcx3fsu5dctsm3pyqkh6];嵌套异常为org。冬眠例外ConstraintViolationException:无法执行语句

共有1个答案

寇和璧
2023-03-14

据我所知,如果实体不存在,jparepository将插入,如果实体存在,jparepository将合并。那么,为什么会出现错误:

它将只是一个实体存在意味着一个具有相同主键的实体存在,其他列/属性对此并不重要(无论是否唯一)。

JPA尝试插入异常时抛出异常(因为主异常不存在),但由于违反了唯一约束,异常失败。

如果您对主键使用GeneratedValue,它不会合并新创建的对象,而是为它们分配一个新id并插入它们(由于唯一约束而失败)。

如果要合并对象,需要使用不同的主键(非GeneratedValue)或修改现有对象(如服务1)。

如何完成此单元测试以检查是否存在错误或异常?

如果您希望出现异常,只需使用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);
}
 类似资料:
  • 问题内容: 当违反唯一约束时,将引发a。但是可能有多种原因抛出异常。我如何才能发现违反了唯一约束? 问题答案: 我如何才能发现违反了唯一约束? 异常是链接在一起的,您必须递归调用以获取提供程序特定的异常(并可能转到),以将其转换为应用程序可以很好地为用户处理的内容。下面将打印异常链: 对于异常处理和“翻译”,您可以执行类似于Spring的操作(请参阅各种类,例如,以获取想法)。 所有这些都不是很好

  • 问题内容: 我将Elasticsearch用作文档数据库,并且我创建的每个记录都有一个GUID ID,系统将其用作记录ID。商界人士希望提供一种功能,使用户可以基于日期和迄今为止在这一天/每月创建的记录数来拥有自己的自动文件名约定。 我需要防止重复的用户文件名。有没有一种方法可以将索引字段设置为唯一?像sql唯一约束一样? 问题答案: 您需要使用应该唯一的字段作为文档的ID。默认情况下,具有现有I

  • 问题内容: 下面的代码段检查给定数字是否为质数。有人可以向我解释为什么这行得通吗?该代码在为Java考试提供给我们的学习指南中。 问题答案: 整体理论 条件询问是否可以被整除 素数的定义是 一个只能被自己和1整除的数字 因此,如果您测试2到number之间的所有数字,并且没有一个数字能被整除,则它是质数,否则就不是质数。 当然,您实际上不必一路前进,因为不能被一半以上的东西完全整除。 具体章节 W

  • 这是我的JPA实体类: 这个类有一个相当复杂的唯一约束:的组合被认为是唯一的。 所以我在类中添加了以下约束注释: 当我尝试练习我的课时,我得到以下例外情况: 异常要点是: 如果我没有在幕后为单个实体类指定该约束,Hibernate将生成两个表:一个表用于所有“简单”实体数据,另一个表用于实体数据: ... 这个问题以前读: JPA:跨集的唯一约束(...另一个表上的唯一约束) 进一步思考我的问题,

  • 问题内容: 我确实在项目中的三个模型对象之间有关系(文章末尾的模型和存储库片段)。 当我调用它时,会触发三个选择查询: (“ sql”) (对我而言)这是非常不正常的行为。据阅读Hibernate文档后所知,它应该始终使用JOIN查询。在类中更改为 查询时(带有附加SELECT 的查询)没有任何区别,而在类更改为 (使用JOIN查询时)则没有变化。 当我使用抑制射击时,有两个选择: 我的目标是在所

  • 我正在组织。冬眠LazyInitializationException异常。据我所知,之所以会出现此问题,是因为我在用户实体中懒散地获取了概要文件对象,并且在初始化代理对象之前,会话已关闭。 执行findAll()方法后会话是否关闭?是否有其他选项可以在同一事务中执行findAll()方法并进行解析,而不是在findAll()方法中进行解析? 我只想知道当调用服务中的findAll方法和UserU