我正在使用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找到的信息(数据库条目/密钥存在于数据库中)?我们怎么检查呢?
答案 0 :(得分:0)
没有这样的方法。 Hibernate无法确定主键是否存在,除非它本身会发出SQL查询。 Hibernate假定此检查由应用程序逻辑完成,以使其成为性能优化的问题。
Hibernate必须注意到重复密钥问题的唯一机会是来自数据库(或JDBC层)的SQLException,通知id字段的唯一约束违规。并且如果发生SQLException,则应该将Hibernate会话视为无效(因为Hibernate无法确保将拦截器和侦听器处理考虑在内的有效状态)。
因此,除非您可以提供额外的逻辑,以确保通过使用其他计数器,批量获取和保留免费ID或使用应用程序范围来确保数据库中尚未存在密钥,因此发布额外查询的弹簧方式是可行的方法用于同步实体ID分配的事件/消息传递解决方案。