Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javax保存重复行时的唯一约束行为_Java_Postgresql_Hibernate_Spring Boot_Spring Data - Fatal编程技术网

Javax保存重复行时的唯一约束行为

Javax保存重复行时的唯一约束行为,java,postgresql,hibernate,spring-boot,spring-data,Java,Postgresql,Hibernate,Spring Boot,Spring Data,假设我在Postgresql数据库中有一个表: CREATE TABLE FOO ( ID INT PRIMARY KEY NOT NULL, NAME CHAR(50) UNIQUE NOT NULL ); 它是由hibernate在Spring引导应用程序中创建的 我想插入以下内容: INSERT INTO FOO (ID, NAME) VALUES (1, "BAR"); INSERT INTO FOO (ID, NAME) VALUES (2,

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

CREATE TABLE FOO (
   ID INT PRIMARY KEY      NOT NULL,
   NAME           CHAR(50) UNIQUE NOT NULL
);
它是由hibernate在Spring引导应用程序中创建的

我想插入以下内容:

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块中包装每一行,就可以在不考虑结果的情况下尝试插入

问题是我不能使用createdrophibernate方法,因为模式中还有其他不能丢失的表

您可以在这里使用try catch block,但我认为对于唯一字段,在持久化实体之前,我们应该每次检查数据库字段中是否存在,这样它将返回它的保证,我认为这是更好的方法,因为在try-catch的情况下,如果我们将处理ConstraintViolationException JDBCException的实现,这表明请求的DML操作导致违反定义的完整性约束。在DML操作导致违反的任何情况下都可能发生此异常,因此最好确保我们的字段是唯一的,我们需要在持久化之前检查它,如果存在实体,我们可以为用户或日志显示用户友好的消息

在您的情况下,代码如下所示:

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

我想弄清楚的是,如果没有将每一行都包装在if/else或try/catch块中的方法,那么这样做有什么问题?但是无论如何,有更好的方法可以做到这一点——请看@ScaryWombat,这是一个很好的信息,但我不能删除当前的db。还有其他不能丢失的表。你链接的帖子提到了策略。是否有一种插入数据但不删除表的更新策略?我不是告诉您删除任何内容-请阅读接受的答案。正如我所问的,try-catch有什么问题?