【发布时间】:2016-05-08 23:35:56
【问题描述】:
我有一个类似(id INTEGER, sometext VARCHAR(255), ....) 的表,其中id 作为主键,对sometext 有一个唯一约束。它用于网络服务器,其中请求需要找到与给定sometext 对应的id(如果存在),否则插入新行。
这是对该表的唯一操作。此表没有更新,也没有其他操作。它的唯一目的是持续不断地遇到sometext 的值。这意味着我不能删除id 并使用sometext 作为PK。
我执行以下操作:
- 首先,我查阅自己的缓存以避免任何数据库访问。几乎总是这样,我已经完成了。
- 否则,我使用 Hibernate Criteria 来查找
sometext所在的行。通常,这行得通,我已经完成了。 - 否则,我需要插入一个新行。
这很好用,除非有两个具有相同sometext 的重叠请求。然后ConstraintViolationException 结果。我需要INSERT IGNORE 或INSERT ... ON DUPLICATE KEY UPDATE(Mysql 语法)或MERGE(Firebird 语法)之类的东西。
我想知道有哪些选择?
AFAIK Hibernate merge 仅适用于 PK,因此不合适。我想,本机查询可能有帮助,也可能没有,因为它可能会在第二次 INSERT 发生时提交,也可能不会提交。
【问题讨论】:
-
我不明白为什么你不能使用 sometext 作为 PK。
-
另外,你为什么不能捕获 ConstraintViolationException(并忽略它)?
-
@Thilo 1. 因为我需要一个数字而不是文本。这就是我使用
id的原因。也许我可以使用sometext并将数字存储在另一列中(我可以通过其他方式保证唯一性)。 +++ 2. 如果我知道它不是由其他原因引起的,我可以。但是表名在异常中不可用。此外,它发生在SessionImpl.flush(而不是 INSERT)中,这很可能意味着没有任何内容被存储。 -
Re:2 所以你在同一个事务中做其他事情?有必要吗?
-
或者只运行
@Transactional(propagation = Propagation.REQUIRES_NEW)下的编号,让它在自己的单独事务中运行。
标签: java hibernate unique-key