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

应该有一种方法可以捕获休眠中找到的信息(数据库中的条目/密钥存在于数据库中)吗?我们如何检查呢?

最佳答案

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

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

因此,发出额外查询的春季方式是必经之路,除非您可以使用其他计数器,批量获取和保留免费ID或使用应用程序范围内的事件/消息传递来提供其他逻辑来确保该密钥在数据库中尚不存在,同步实体ID分配的解决方案。

09-11 17:46
查看更多