Hibernate:在没有约束的情况下强制执行SQL唯一性

时间:2011-12-06 23:14:24

标签: sql hibernate constraints unique-constraint

我正在使用Hibernate开发一个应用程序。我插入的其中一个字段在表格中必须是唯一的。这里的问题是该字段不是主键,底层数据库不支持“UNIQUE”约束。所以我必须在我的应用程序代码中强制执行此操作。

这个伪代码是我目前所拥有的:

void insert(Data data) {

  beginTransaction();

  boolean exists = existsRecordWithName(data.name);

  // Line 7

  if (exists == false) {
    insertRecord(data);
  } else {
    display("Name already exists in database!");
  }

  commit();
}

但是如果两个不同的进程同时插入数据,并且两个进入第7行,他们会认为数据库中没有其他记录具有相同的名称,并且他们都会插入它 - >结果是重复。

那么我怎样才能以这种方式强制实现独特性呢?如果我使用的是纯SQL,我会尝试锁定表,但我正在寻找一个涉及Hibernate标准功能的更高级别的解决方案,所以如果我有一天会改变后端,它会继续工作。

感谢任何帮助!

2 个答案:

答案 0 :(得分:1)

您无法使用应用程序代码强制执行唯一约束。严格来说,约束适用于所有用户。您在应用程序代码中所做的只适用于碰巧使用该应用程序代码的用户。例如,应用程序代码中的约束不适用于使用命令行工具或GUI实用程序访问数据库的DBA或开发人员。

话虽如此,SQL DBMS通常会支持锁和事务。如果您不能通过声明列唯一来强制执行唯一性,那么您的下一个最佳选择是明确锁定表,并将更改包装在可序列化的事务中。我认为锁定表应该足够了,但我不打算在不支持唯一约束的系统上下注。

什么dbms不支持唯一约束?我很确定我从未看到过这样的事情,而且差不多30年前我就开始使用数据库。

答案 1 :(得分:0)

你可以使用hibernate进行锁定(LockMode),前提是你的数据库支持它,但是使用insert进行锁定是一项棘手的工作(如何锁定尚不存在的东西)。顺便说一下,如果你为这个实体做一个唯一的=“真”会发生什么? hibernate会抛出一个错误,说它不能,或者它是否允许重复?我假设你已经正确实现了equals和hashcode方法。

在上面的代码大纲中,您可以实习()名称并围绕名称上的代码执行同步块 - 这可能有效。