当我无法输入重复的数据库条目时,如何知道?

时间:2013-09-29 14:43:10

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

我正在使用Spring Data JPA和Hibernate。

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

当我使用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首先检查密钥是否存在于数据库中,然后继续执行插入。

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

1 个答案:

答案 0 :(得分:0)

没有这样的方法。 Hibernate无法确定主键是否存在,除非它本身会发出SQL查询。 Hibernate假定此检查由应用程序逻辑完成,以使其成为性能优化的问题。

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

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