Javax Unique Contraints行为持久化重复行

时间:2017-04-24 00:23:01

标签: java postgresql hibernate spring-boot spring-data

假设我在Postgresql数据库中有一个表:

CREATE TABLE FOO (
   ID INT PRIMARY KEY      NOT NULL,
   NAME           CHAR(50) UNIQUE NOT NULL
);

是由Spring引导应用程序中的hibernate创建的

我要插入以下内容:

INSERT INTO FOO (ID, NAME) VALUES (1, "BAR");
INSERT INTO FOO (ID, NAME) VALUES (2, "BAZ");
INSERT INTO FOO (ID, NAME) VALUES (3, "ZIP");

作为以下类中的种子数据:

@Component
public class SeedDB implements CommandLineRunner {

  private final FooRepository fooRepository;

  @Autowired
  public SeedDB(FooRepository fooRepository) {
    this.fooRepository = fooRepository;
  }

  @Override
  public void run(String... strings) throws Exception {
    fooRepository.save(new Foo("bar"));
    fooRepository.save(new Foo("baz"));
    fooRepository.save(new Foo("zip"));
  }
}

所有这一切只是说,只要db为空,这就行得很好。但如果每次应用程序旋转时将其设置为运行,则唯一约束会导致以下错误:

Caused by: org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [ukjsk1parw92chjvhsj49tl7492]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
...
Caused by: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "ukjsk1parw92chjvhsj49tl7492"
Detail: Key (name)=(bar) already exists.
我想,这是有道理的。我想弄清楚的是,如果有一种方法,没有包装if / else或try / catch块中的每一行,尝试插入而不考虑结果?

问题在于我无法使用create-drop hibernate方法,因为还有其他表在模式中不会丢失。

1 个答案:

答案 0 :(得分:1)

您可以在这里使用try catch块,但我认为在unique字段的情况下我们应该在每次数据库中检查(字段是否存在),然后才能保留我们的实体,这样它就会保证它,我认为这是更好的方法,因为如果我们将处理 ConstraintViolationException Implementation of JDBCException indicating that the requested DML operation resulted in a violation of a defined integrity constraint.),尝试捕获的情况下,这种例外情况可能发生在any case of DML operation resulted in a violation,所以最好确保我们的文件是唯一的,我们需要在坚持之前检查它,如果存在实体我们可以为用户或日志显示用户友好的消息。

在你的案例代码中会喜欢:

if(fooRepository.countByFiledName("bar")==0) {
 fooRepository.save(new Foo("bar"));
}