【问题标题】:How do i get to know when I fail to enter a duplicate database entry?我如何知道我无法输入重复的数据库条目?
【发布时间】:2013-10-05 10:29:56
【问题描述】:

我在 Hibernate 中使用 Spring Data JPA。

我有一个复合键映射到数据库表的类。

当我使用 JPARepository 扩展接口对象执行保存操作时,我在控制台中看到以下日志:

Hibernate: select rolefuncti0_.functionalityId as function1_4_0_, rolefuncti0_.roleId as roleId2_4_0_ from RoleFunctionality_Mapping rolefuncti0_ where rolefuncti0_.functionalityId=? and rolefuncti0_.roleId=?
Hibernate: insert into RoleFunctionality_Mapping (functionalityId, roleId) values (?, ?)

这是我用相同的数据重复操作时看到的:

 Hibernate: select rolefuncti0_.functionalityId as function1_4_0_, rolefuncti0_.roleId as roleId2_4_0_ from RoleFunctionality_Mapping rolefuncti0_ where rolefuncti0_.functionalityId=? and rolefuncti0_.roleId=?

看来Spring Data首先检查数据库中是否存在Key,然后继续执行插入。

应该有办法捕获hibernate找到的信息(数据库条目/密钥存在于数据库中)?我们如何检查?

【问题讨论】:

    标签: java mysql spring hibernate spring-data-jpa


    【解决方案1】:

    没有这样的方法。 Hibernate 不能确定主键是否存在,除非它自己发出一个 SQL 查询。 Hibernate 假设这个检查是由应用程序逻辑完成的,以允许这成为性能优化的问题。

    Hibernate 必须注意重复键问题的唯一机会是来自数据库(或 JDBC 层)的 SQLException 通知 id 字段的唯一约束违规。与往常一样,如果发生 SQLException,则应将 Hibernate 会话视为无效(因为考虑到拦截器和侦听器处理,Hibernate 无法确保有效状态)。

    因此,发出额外查询的弹簧方式是可行的方法,除非您可以提供额外的逻辑,通过使用额外的计数器、批量获取和保留空闲 ID 或使用应用程序范围来确保密钥不存在于数据库中同步实体 ID 分配的事件/消息传递解决方案。

    【讨论】:

    • 感谢您的回答。我可以欣赏 Spring 在这里所做的事情。我在想应该有某种可以从 Spring 获得的信息,它会以任何其他方式返回/提供给应用程序 - 如果在重复条目的情况下它不会继续插入。 (Spring 在找到现有的主键后做出决定(基于一些信息)不插入。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-05
    • 2011-10-17
    • 2019-11-29
    • 2013-02-10
    • 2023-04-04
    • 2023-03-04
    • 1970-01-01
    相关资源
    最近更新 更多